Перенос данных с 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).).