База большая, хаотичная и в целом - внушает ужас. Увы, отнюдь не объёмами, но скорее качеством данных.
Дабы вы поняли всю прелесть и пикантность ситуации, добавлю - база мало того, что неиндексированная, так ещё и с отсутствующим ключевым полем.
Хранится всё это Щастье в dbf. Разного рода вспомогательные базы, базочки, базюшески и просто обновления - в том же dbf.
Поскольку с dbf я дружу слабо, а с MySQL - средне, было принято решение - "загнать эту ... базу в мускуль, а там видно будет".
Как это ни смешно, решение оказалось правильным. С другой стороны, есть подозрение, что правильным было бы любое решение, потому что один из принятых в этой конторе методов обработки информации заключался в "распечатать всё, а потом силами нескольких человек найти нужное в распечатках, а потом вручную вбить обратно".
Заканчивая лирическое отступление, расскажу - как я загоняю dbf-ки в MySQL и потом выковыриваю их обратно.
aptitude search навёл меня на утилиту dbf2mysql
Я не буду пересказывать здесь ман, вскользь отмечу только, что ключ "перевести имена полей в нижний регистр" работает, а вот "перевести значения полей в нижний/верхний регистр" - не работает.
У утилиты этой есть один, но существенный на мой взгляд, недостаток.
Автор её и слыхом не слыхивал о существовании кодировок, отличных от latin1.
В результате имеем таблицу в кодировке latin1, набитую данными в кодировке CP866.
Но нас таким не напугаешь. Возможно кто-то применит секретное заклинание alter table, сменит тип данных с текстового на blob, выправит кодировку, а потом сменит тип данных обратно, но это не мой путь. Этих самых полей у меня - неисчислимое множество (ну вру. Исчислимое, что уж там. Но всё равно - много).
Выручает старый-добрый mysqldump с принудительным выставлением кодировки в latin1.
Обрабатываем полученный файл
Дабы работать было удобнее, добавляю отдельное поле типа int, заполняю его автоинкрементом и индексирую по нему. Иначе - совсем грустно. Но это уже сугубо моя локальная специфика.
Самое интересное начинается, когда приходит время загнать данные из MySQL обратно в dbf. Вот тут уже - чистое шаманство.
Вышеупомянутая утилита dbf2mysql имеет и оборотную сторону mysql2dbf. И даже вроде как работает, но...
Но о кодировках, отличных от latin1 можно забыть.
Но настоящего джедая не напугать такими мелочами.
Берём, делаем выборку из MySQL, посредством INTO OUTFILE формируем csv, открываем готовую dbf-ку с нужной структурой редактором dbf от pssoft.ru (спасибо автору), удаляем все данные и импортируем туда данные из csv. Одно уточнение - данные в csv должны быть в CP1251, но это такие мелочи...
От счастливого финала нас отделяет только N-ное количество щелчков мышью. Каждое поле dbf-а нужно сопоставить полю csv-шки. Автоматизировать - никак. У меня таких полей - 70.
Клик-клик-клик...
Клик-клик-клик...
Клик-клик-клик...
ДААА! Экспорт в dbf и вожделенный файлик на диске, будь он неладен.
К чему всё это? К тому, что если кто знает способ лучше - я просто изнемогаю от желания его узнать. А пока тихо радуюсь, что результаты обработки в 90% случаев нужны не в dbf, а в xls, получить который из csv - дело пары минут.
Занавес.
Сразу видно - не ленивый человек. (Почему бы не допилить dbf2mysql ?)
ОтветитьУдалитьЧто-то мне подсказывает, что dbf2mysql писано на каком-нибудь перле. ;) Ну или питоне, не важно в общем. Скажем так: на скриптовом языке. И ИМХО допилить его - нефиг делать. ;) К стати надо глянуть...
ОтветитьУдалитьГлянул. Во блин! Не лень было кому-то лабать это дело на сях?... :( Ну тогда надо исходники смотреть конечно...
ОтветитьУдалитьНа скриптовом языке, как и писал(а) Olly Cat, сам мигратор сделать. дело 1 часа(с перерывами на кофеёк) :))
ОтветитьУдалитья такое на ПХП ваял... исходников правда неосталось..
Пока по моим оценкам трудозатраты на написание скрипта превышают трудозатраты на "конвертацию вручную". Поэтому делаю "закат солнца вручную".
ОтветитьУдалитьВ будущем - придётся писать, без вариантов.
Такая же проблема на производстве. Куча связанных dbf'ок с 40+ полями общим размером 1G+. Использую Tcl/Tk+ODBC от VFP, делаю отчеты через COM в word/excel, пока не парюсь;)
ОтветитьУдалитьПо поводу закачки из MySQL в DBF. Вы получили cvs файл, можете, как Вы написали, закачать его в xls. Ну и откройте его Excel-ем и из Excel-я сохраните как dbf. По идее проблем не должно быть. Сам так сохраняю постоянно, правда не из dbf-а. :)
ОтветитьУдалитьХмм... А как оно угадает, какой тип полей мне нужен?
ОтветитьУдалитьУ меня жёстко заданный формат dbf-таблицы
Написал скриптик (является лишь примером, используйте на свой страх и риск):
ОтветитьУдалить#bash
#из dbf в mysql
dbf2mysql -vvv -d databasename -t tablename -c -h localhostorother -P mysqlpassword -U myysqllogin file.dbf
mysqldump -umysqllogin -pmysqlpasswordorblank --default-character-set=latin1 databasename tablename>out.sql
iconv -f cp866 -t utf-8 out.sql>outtmp.sql
more outtmp.sql|sed 's/latin1/utf8/'>out.sql
mysql -umysqllogin -pmysqlpasswordorblank -T --show-warning -e "delete from tablename" databasename
mysql -umysqllogin -pmysqlpasswordorblank -T --show-warning databasename<out.sql
rm out.sql&rm outtmp.sql
#Теперь обратно
mysqldump -umysqllogin -pmysqlpasswordorblank databasename tablename>out.sql
more out.sql|sed 's/utf8/latin1/'>outtmp.sql
iconv -t cp866 -f utf-8 outtmp.sql>out.sql
mysql -umysqllogin -pmysqlpasswordorblank -T --show-warning -e "delete from tablename" databasename
mysql -umysqllogin -pmysqlpasswordorblank -T --show-warning databasename<out.sql
mysql2dbf -vvv -d databasename -t tablename -h localhostorother -P mysqlpassword -U mysqllogin outfile.dbf
rm out.sql&rm outtmp.sql
В моем случае file.dbf содержал char, integer, double и date. outfile.dbf спокойно открылся в FoxPro под Win.