我正在编写python脚本来将表从MSSQL数据库同步到Postgresql数据库。原作者倾向于使用超宽表,其中有许多区域连续的NULL
孔。在
为了提高插入速度,我在execute()
之前将大量记录序列化为以下格式的字符串
INSERT INTO A( {col_list} )
SELECT * FROM ( VALUES (row_1), (row_2),...) B( {col_list} )
在行序列化期间,无法在python中确定NULL
或{timestamp
列、integer
列等中的所有NULL
值都需要显式类型转换为正确的类型,否则Pg会对此进行抱怨。在
目前,我正在检查dbapiconnection.description
属性,并比较每个列的列类型转换代码,并根据需要添加::timestamp
之类的类型转换。在
但这感觉很麻烦,因为需要做额外的工作:驱动程序已经将数据从文本转换为正确的python数据类型,现在我必须用这些多个None
为column重新进行此操作
有没有更好的方法可以优雅而简单地解决这个问题?在
您可以尝试从数据创建json,然后使用
json_populate_record(..)
从json创建行集。在您可以使用
json_populate_recordset(..)
一次性对多行执行相同的操作。只需传递json值,这是json的数组。确保它不是json数组。在这样就可以了:
'[{"id":1,"dat":null,"val":6},{"id":3,"val":"tst"}]'::json
这不是:
^{pr2}$array['{"id":1,"dat":null,"val":6}'::json,'{"id":3,"val":"tst"}'::json]
如果您不需要
SELECT
,请使用@Nick's answer。如果您需要它(比如CTE多次使用输入行),那么根据用例的细节,有一些变通方法。在
例如,在处理完整行时:
{col_list}
在这种特殊情况下是可选的噪声,因为我们无论如何都需要提供完整的行。在详细说明:
不必从
SELECT
插入,您可以直接将VALUES
子句附加到INSERT
,即:当您从查询中插入时,Postgres在试图推断列类型时隔离检查查询,然后尝试强制它们与目标表匹配(结果发现它无法匹配)。在
当您直接从
VALUES
列表插入时,它在执行类型推断时知道目标表,然后可以假定任何非类型化的NULL
与相应的列相匹配。在相关问题 更多 >
编程相关推荐