以下是通过我正在运行的脚本检索到的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表。主键列是唯一标识符,所以我很困惑这个错误的来源。
任何有用的想法或反馈。
由于
答案 0 :(得分:0)
MySQL中的binary
列已转换为Unicode
PostgreSQL列。
我认为它只是被错误地转换,为不同的源二进制值制作相同的unicode字符串。因此,您导入的记录很少,然后主键会重复出现错误。
最好在PostgreSQL端使用二进制字段(https://www.postgresql.org/docs/9.0/static/datatype-binary.html)或使用一些安全的二进制文本转换(如base64 encoding)。