MYSQL到PostgreSQL数据迁移

时间:2017-10-25 16:15:54

标签: python postgresql sqlalchemy postgresql-9.3

以下是通过我正在运行的脚本检索到的Customers表元数据的摘录。该脚本调用一个服务,该服务通过JSON从MYSQL数据库中检索元数据和数据,然后将元数据(例如数据类型,列约束)转换为POSTGRESQL可读语法,并将数据加载到Postgresql数据库中。 请注意,主键列id属于TYPE BYTEA:

from sqlalchemy.dialects.postgresql import BYTEA

转换前Customers表的元数据:

('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'']])

这是使用sqlalchemy转换后的元数据到POSTGRESQL可读语法:

[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)])])

我还根据Boris的评论将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 个答案:

答案 0 :(得分:0)

MySQL中的binary列已转换为Unicode PostgreSQL列。

我认为它只是被错误地转换,为不同的源二进制值制作相同的unicode字符串。因此,您导入的记录很少,然后主键会重复出现错误。

最好在PostgreSQL端使用二进制字段(https://www.postgresql.org/docs/9.0/static/datatype-binary.html)或使用一些安全的二进制文本转换(如base64 encoding)。