Я пишу инструмент переноса данных в БД, используя язык выражений SQLAlchemy в качестве основного инструмента.
Моя исходная база данных может быть в UTF8 или в SQL_ASCII. Моя целевая БД всегда будет в UTF8.
Я использую драйвер psycopg2 в SQLAlchemy 0.6.6
Мой общий процесс миграции выглядит следующим образом:
for t in target_tables:
log.info("Migrating data from %s", t.fullname)
source = self.source_md.tables[self.source_schema + "." + t.name]
for row in source.select().execute():
with sql_logging(logging.INFO):
conn.execute(t.insert(), row)
Если я не установил что-либо связанное с кодировкой на движках, я получаю это, когда перебираю результаты select()
:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)
Если я установлю use_native_unicode=True, encoding='utf-8'
для двигателей, я получаю это при попытке вставить новую строку:
sqlalchemy.exc.DataError: (DataError) invalid byte sequence for encoding "UTF8": 0xeb6d20
HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
'INSERT INTO project_ghtests_survey000005.employees (first_name, employee_id) VALUES (%(first_name)s, %(employee_id)s)' {'first_name': 'Art\xebm', 'employee_id': '1234'}
Обновить данные
Чтобы сделать запросы немного быстрее, вот программный стек в игре:
- кодировка source_db:
SQL_ASCII
- кодировка target_db:
UTF8
- питон 2.7
- sqlalchemy 0.6.6
- psycopg2 2.2.2
- Сервер PostgreSQL 8.2