Thursday, August 5, 2010

dbf2csv

Понадобилось перегнать мне табличку из dbf в mysql. Ну и еще необходимо учесть тот нюанс, что поля в mysql базе будут называться по другому. Задачу разделим на 3 этапа:
1. Преобразование dbf файла в csv
Я загуглил на фразу "dbf2csv.pl" и в первой же ссылке нашел то, что мне надо.

2. Если у нас в базе данных имена полей различаются, поправим шапку в csv фале. И еще одна маленькая правка - удаляем из файла все кавычки (например, с помощью replace в текстовом редакторе)

3. Конвертируем csv файл в sql
Например, воспользуемся моим самописным скриптом на python. По умолчанию читает csv файл из stdin, однако можно указать входной файл с помощью опции -f. Так же дополнительно можно указать имя БД и название таблицы с помощью опци -d и -t. Ну и не забудьте про кодировки, скорее всего в Базе и dbf файле они будут различны, поэтому при добавлении записей не забываем установить нужную кодировку опцией set names 'utf8';








#!/usr/bin/env python
import sys
from optparse import OptionParser

def main():
parser = OptionParser()
parser.add_option("-f", "--from-file", dest="fromfile",
help="read csv data from FILE")
parser.add_option("-d", "--database", dest="database",
help="database name for generating database create statement")
parser.add_option("-t", "--table", dest="table",
help="table name from generating valid queries")
parser.add_option("-s", "--separator", dest="separator",
help="separator for new csv file")
(options, args) = parser.parse_args()

table = 'tableName'
separator = ','
if options.fromfile == None:
infile = sys.stdin
else:
infile = open(options.fromfile, 'r')
if options.table != None:
table = options.table
if options.separator == None:
separator = ','
else:
separator = options.separator
if options.database != None:
# need create database statement
print "DROP DATABASE IF EXISTS " + options.database + ";"
print "CREATE DATABASE " + options.database + " DEFAULT CHARACTER SET 'utf8';"
print "USE " + options.database + ";"

line = infile.readline()
fields = line.split(separator)

for line in infile:
elems = line.split(separator)
if len(elems) != len(fields):
print "Error in csv file! Count of columns don't correspondence to rows"
sys.exit(-1)

print "insert into '" + table + "' (",

iter1 = True
for field in fields:
if iter1:
iter1 = False
else:
print ',',

print field.strip(),

print ') \n\tvalues (',

iter1 = True
for elem in elems:
if iter1:
iter1 = False
else:
print ',',

print "'"+elem.strip()+"'",

print ');'
main()

Tuesday, July 28, 2009