Перенос данных с MYSQL на PostgreSQL

Ниже приведена выдержка из метаданных таблицы "Клиенты", получаемых с помощью запускаемого мной скрипта. Сценарий вызывает службу, которая извлекает метаданные и данные из базы данных MYSQL через JSON, затем преобразует метаданные (например, типы данных, ограничения столбцов) в читаемый синтаксис POSTGRESQL и загружает данные в базу данных Postgresql. Обратите внимание, что столбец первичного ключа id имеет тип BYTEA:

from sqlalchemy.dialects.postgresql import BYTEA

Метаданные таблицы "Клиенты" до конвертации:

('columns before conversion', [[u'id', u'binary(16)', u'NO', u'PRI', None, u''], 
[u'person_id', u'varchar(255)', u'NO', u'', None, u''], [u'ident_id', u'varchar(255)', u'NO', u'', None, u''],[u'seller_id', u'binary(16)', u'YES', u'MUL', None, u''], [u'inserted_at', u'datetime', u'NO', u'', None, u'']])

Это преобразованные метаданные в читаемый синтаксис POSTGRESQL с использованием sqlalchemy:

[OrderedDict([('name', u'id'), ('type_', <class 'sqlalchemy.dialects.postgresql.base.BYTEA'>), ('nullable', False), ('default', None), ('autoincrement', False), ('primary_key', True), ('unique', False)]), OrderedDict([('name', u'person_id'), ('type_', <class 'sqlalchemy.sql.sqltypes.String'>), ('nullable', False), ('default', None), ('autoincrement', False), ('primary_key', False), ('unique', False)]), OrderedDict([('name', u'ident_id'), ('type_', <class 'sqlalchemy.sql.sqltypes.String'>), ('nullable', False), ('default', None), ('autoincrement', False), ('primary_key', False), ('unique', False)]), OrderedDict([('name', u'seller_id'), ('type_', <class 'sqlalchemy.sql.sqltypes.Unicode'>), ('nullable', True), ('default', None), ('autoincrement', False), ('primary_key', False), ('unique', False)]), OrderedDict([('name', u'inserted_at'), ('type_', <class 'sqlalchemy.sql.sqltypes.DateTime'>), ('nullable', False), ('default', None), ('autoincrement', False), ('primary_key', False), ('unique', False)])])

Я также преобразовал значения в id column в Base64 на основании комментария Бориса ниже:

                df['id'] = df['id'].apply(lambda x: base64.b64encode(x))

Тем не менее, я все еще получаю сообщение об ошибке при загрузке данных:

(psycopg2.IntegrityError) duplicate key value violates unique constraint "customers_pkey" DETAIL: Key (id)=(aion}{�}�HQDAS�987) already exists

Я в недоумении, потому что таблица Customers удаляется и создается каждый день до импорта данных. Столбец первичного ключа является уникальным идентификатором, поэтому я озадачен, откуда эта ошибка.

Любые идеи или отзывы, которые будут очень полезны.

Спасибо

1 ответ

У тебя есть binary столбец в MySQL, который преобразуется в Unicode Столбец PostgreSQL.

Я думаю, что он просто неправильно конвертируется, создавая одну и ту же строку Юникода для разных исходных двоичных значений. Таким образом, вы получаете несколько импортированных записей, а затем повторяется первичный ключ, что вызывает ошибку.

Лучше использовать двоичное поле на стороне PostgreSQL ( https://www.postgresql.org/docs/9.0/static/datatype-binary.html) или использовать некоторое безопасное преобразование двоичного в текст (например, кодирование base64).).

Другие вопросы по тегам