Fórum Root.cz
Hlavní témata => Server => Téma založeno: Jardaa 18. 05. 2013, 00:58:35
-
Ahoj narazil jsem na pro mě docela složitou úlohu, v této oblasti jsem začátečník.
Potřeboval bych importovat seznam adres v ČR do své databáze (mysql)
Podařilo se mi dopátrat na stránkách Ministerstva vnitra (http://aplikace.mvcr.cz/adresy/) soubor XML (http://aplikace.mvcr.cz/adresy/Download.aspx) ale nevím, jak ho co nejjednodušeji dostat do databáze. XSLT transformace pohoří na out of memmory. Přímý import se mi také nedaří (LOAD XML LOCAL INFILE 'E:\Downloads\Adresy_CR\adresy.xml' INTO TABLE addresses ROWS IDENTIFIED BY 'nazev') - #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'XML LOCAL INFILE 'E:\Downloads\Adresy_CR\adresy.xml' INTO TABLE addresses ROWS I' at line 1
Pokud existuje někde přímo nějaký tool, který to dokáže exportovat do jiného formátu budu rád za jakékoliv tipy.
Díky za jakoukoliv pomoc
-
tak proste zvetsi pamet
-
Mám 8 266 644 K, z toho nějakých 5 120 000 K volných to je snad dostatečné množství :)
Spíše mám pocit ze to nezvládá starší verze programu XMLspy - mám verzi 2008 novější si prostě kupovat nebudu. Tedy pokud máte doporučení na nejaký jiný tool vhodný pro XSL transformaci, nejlépe opensource budu rád.
Něco v javě typu Netbeans prosím nee trvá to neuvěřitelně dlouho než dokáže s tím souborem pracovat a ani pak to není zázrak. Přece jenom se pohybujeme u docela velkého XML souboru - 49,5 MB (51 934 835 bytes)
Jěště zkouším soubor rozdělit na více částí a zdá se, že je to lepší ale hodně manuální práce, které bych se pokudmožno chtěl vyhnout kvůli automatickým update v budoucnu.
-
Jaka manualni prace? To se snad dela skriptem, ktery to rozdeli po X adresach.
-
Posledně jsem to převáděl v PHP na NB s 256 MB RAM a nebyl s tím žádný problém. Podobně snadné by to mělo být i v Pythonu či Javě.
-
Adresy má na starost dnes ČÚZK, který vede RÚIAN (registr územní identifikace, adres a nemovitostí). Taky nabízí ke stažení adresní místa (http://nahlizenidokn.cuzk.cz/StahniAdresniMistaRUIAN.aspx (http://nahlizenidokn.cuzk.cz/StahniAdresniMistaRUIAN.aspx)) a to ve formátu CSV.
-
XSLT transformace je asi nejhorší způsob, jak to udělat.
Je potřeba napsat jednoduchý parser, který bude dokument postupně zpracovávat a jednotlivé položky ukládat do databáze. Ideálně SAX, ne DOM. V pythonu bych to odhadoval tak na třicet řádků.
-
Z odkazu, co poslal jan.xxx (http://nahlizenidokn.cuzk.cz/StahniAdresniMistaRUIAN.aspx) jsem to zkusil a pěkně se to do DB naházelo..
### Vytvořit databázi s potřebným kódováním
CREATE DATABASE IF NOT EXISTS `adresy` DEFAULT CHARACTER SET latin2 COLLATE latin2_general_ci
### Vytvořit tabulku
CREATE TABLE IF NOT EXISTS `adresni_mista` (
`kod_adm` int(11) NOT NULL,
`kod_obce` int(11) NOT NULL,
`nazev_obce` text NOT NULL,
`nazev_momc` text NOT NULL,
`nazev_mop` text NOT NULL,
`kod_casti_obce` int(11) NOT NULL,
`nazev_casti_obce` text NOT NULL,
`nazev_ulice` text NOT NULL,
`typ_so` text NOT NULL,
`cislo_domovni` text NOT NULL,
`cislo_orientacni` int(11) NOT NULL,
`znak_cisla_orientacniho` text NOT NULL,
`psc` int(11) NOT NULL,
`souradnice_y` text NOT NULL,
`souradnice_x` int(11) NOT NULL,
`plati_od` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin2;
### Rozbalit zip archiv, kde se vytvoří složka CSV
unzip /cesta/k/archivu.zip
### a pustit po dosazení proměnných tento skript:
#!/bin/bash
CESTA_K_CSV="/cesta/k/CSV" ## cesta, kde jsi rozbalil archiv (cesta až k souborům)
SEZNAM="/tmp/seznam.txt" ## může zůstat přednastaveno, je to jen dočasný soubor
######################
USER="root" ## uživatel do DB
PASSWORD="root" ## heslo do DB
DB="adresy" ## databáze
TABLE="adresni_mista" ## tabulka v DB, kam se budou importovat data
######################
# smaže první řádek v každém souboru:
find $CESTA_K_CSV -type f -exec sed -i '1d' {} \;
# seznam souborů pro import
find $CESTA_K_CSV -type f > $SEZNAM
# import
while read line; do
mysql -u $USER -p$PASSWORD --local_infile=1 $DB -e "LOAD DATA LOCAL INFILE '$line' INTO TABLE $TABLE FIELDS TERMINATED BY ';'"
done < $SEZNAM
rm $SEZNAM;
exit;
Mně to v pohodě naimportovalo..
-
OMG latin... tohle se ti jednou osklive nevyplati.
-
V zásadě používám pouze UTF-8. Jestli jsi to ale zkoušel, tak jsi narazil právě na diakritiku s tímto kódováním.
Když jsem si otevřel soubor z archivu, otevřel se se středoevropským kódováním, takže jsou dvě možnosti:
a) překódovat každý z těch 6ti tísíc souborů nebo kolik jich bylo, byť by to dělal skript
b) přizpůsobit tomu databázi a nedělat si problémy při následných updatech
zvolil jsem tedy b)...
-
Ahoj,
díky za script, všechno hezky naimportuje. Ještě by mě zajímalo, jestli jste nějak řešili optimalizaci celé té tabulky. Protože má 2 920 904 řádků a dotaz na ověření adresy trvá déle než 3s.
Díky, Martin.
-
Jestli je vyhledání adresy nejčastější dotaz (a víc jich nebude), pak se vyplatí nad tím sloupcem vytvořit index a mít indexově organizovanou tabulku, pokud je to možné.
-
XSLT transformace pohoří na out of memmory.
XSLT je fajn a má spoustu dobrých vlastností – jedna z nich je, že se můžeš vracet zpátky, přečíst si tuhle něco, támhle něco, dopočítat pár věcí, pustit for-each cyklus na něčem jiném… ale s tím se pojí i jedna nevýhoda: aby tohle bylo možné, je potřeba mít celý dokument načtený v paměti. Takže XSLT na tuhle úlohu není moc vhodné – dalo by se použít leda tak, že bys transformaci volal na jednotlivé uzly (adresy), ne na celý dokument.
Řešil bych to nejspíš přes SAX – zpracuj si události (uzly), které tě zajímají a za chodu generuj objekty, řádky souboru nebo volej SQL příkazy – tímhle způsobem můžeš zpracovat i „nekonečně“ dlouhý soubor a paměť ti nikdy nedojde :-) Není to moc o jazyku, jako spíš o tech technice práce s XML (SAX vs. DOM).
-
V zásadě používám pouze UTF-8. Jestli jsi to ale zkoušel, tak jsi narazil právě na diakritiku s tímto kódováním.
Když jsem si otevřel soubor z archivu, otevřel se se středoevropským kódováním, takže jsou dvě možnosti:
a) překódovat každý z těch 6ti tísíc souborů nebo kolik jich bylo, byť by to dělal skript
b) přizpůsobit tomu databázi a nedělat si problémy při následných updatech
zvolil jsem tedy b)...
MySQl umi prekodovat vstup sama, staci nastavit koneksnu => pokud mas DB UTF a koneksne reknes, ze je latin, tak to vpohode vlozis a v DB to bude UTF.