Как я могу скопировать данные из SQL_ASCII в базу данных postgresql UTF8 с помощью SQLAlchemy?

1

Я пишу инструмент переноса данных db с использованием языка выражения 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
  • python 2.7
  • sqlalchemy 0.6.6
  • psycopg2 2.2.2
  • Сервер PostgreSQL 8.2
Теги:
character-encoding
unicode
sqlalchemy

2 ответа

1

Оказывается, что решение было установить соединение client_encoding с 'latin1'

Я выполнил это с помощью PoolListener следующим образом:

class EncodingListener(PoolListener):

    def connect(self, dbapi_con, con_record):
        with closing(dbapi_con.cursor()) as cur:
            cur.execute('show client_encoding')
            encoding = cur.fetchone()[0]

        if encoding.upper() == 'UTF8':
            return

        dbapi_con.set_client_encoding('latin1')
0

Поскольку UTF-8 обратно совместим с UTF-8, зачем использовать SQL_ASCII isntead UTF8?

Я думаю, что ваши проблемы с кодированием, вероятно, больше похожи на latin1 или аналогичные кодировки. Не с ASCII до UTF8.

  • 0
    Что ты имеешь в виду? БД уже находится в SQL_ASCII, я не особо об этом говорю.
  • 1
    @Chris R: Я имею в виду, что не имеет значения, указываете ли вы SQL_ASCII или UTF8 для исходной базы данных, поскольку UTF8 обратно совместим с ASCII .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню