Python 如何避免在Postgresql中插入时显式转换NULL
我正在编写python脚本,以便将表从MSSQL数据库同步到Postgresql数据库。最初的作者倾向于使用超宽表,其中有许多区域连续的Python 如何避免在Postgresql中插入时显式转换NULL,python,postgresql,psycopg2,Python,Postgresql,Psycopg2,我正在编写python脚本,以便将表从MSSQL数据库同步到Postgresql数据库。最初的作者倾向于使用超宽表,其中有许多区域连续的NULL孔 为了提高插入速度,我在execute() 在行序列化期间,无法确定python中NULL或None的数据类型。这使工作变得复杂。timestamp列、integer列等中的所有NULL值都需要显式类型转换为适当的类型,否则Pg会对此提出投诉 目前,我正在检查DB API连接。description属性,比较每列的列类型\u代码,并根据需要添加类型转换
NULL
孔
为了提高插入速度,我在execute()
在行序列化期间,无法确定python中NULL
或None
的数据类型。这使工作变得复杂。timestamp
列、integer
列等中的所有NULL
值都需要显式类型转换为适当的类型,否则Pg会对此提出投诉
目前,我正在检查DB API连接。description
属性,比较每列的列类型\u代码,并根据需要添加类型转换,如::timestamp
但这感觉很麻烦,需要做额外的工作:驱动程序已经将数据从文本转换为正确的python数据类型,现在我必须为包含许多None
s的列重做
有没有更好的方法来解决这一问题,使其简洁明了?您可以尝试从数据创建json,然后使用
json\u populate\u record(…)
从json创建行集
您可以使用json\u populate\u recordset(..)
一次性对多行执行相同的操作。只需传递json值,即json数组。确保它不是json数组
这样就可以了:'[{“id”:1,“dat”:null,“val”:6},{“id”:3,“val”:“tst”}]::json
这不是:array['{“id”:1,“dat”:null,“val”:6}'::json,{“id”:3,“val”:“tst”}'::json]
select *
from json_populate_recordset(null::js_test,
'[{"id":1,"dat":null,"val":6},{"id":3,"val":"tst"}]')
您可以尝试从数据创建json,然后使用
json\u populate\u record(..)
从json创建行集
您可以使用json\u populate\u recordset(..)
一次性对多行执行相同的操作。只需传递json值,即json数组。确保它不是json数组
这样就可以了:'[{“id”:1,“dat”:null,“val”:6},{“id”:3,“val”:“tst”}]::json
这不是:array['{“id”:1,“dat”:null,“val”:6}'::json,{“id”:3,“val”:“tst”}'::json]
select *
from json_populate_recordset(null::js_test,
'[{"id":1,"dat":null,"val":6},{"id":3,"val":"tst"}]')
您可以将
值
子句直接附加到插入
,而不是从选择插入,即:
INSERT INTO A ({col_list})
VALUES (row_1), (row_2), ...
当您从查询中插入时,Postgres在尝试推断列类型时会孤立地检查查询,然后尝试强制它们与目标表匹配(结果发现它不能)
当您直接从值列表中插入时,它在执行类型推断时知道目标表,然后可以假定任何未类型化的NULL
与相应列匹配。而不是从选择中插入,您可以将值
子句直接附加到插入
,即:
INSERT INTO A ({col_list})
VALUES (row_1), (row_2), ...
当您从查询中插入时,Postgres在尝试推断列类型时会孤立地检查查询,然后尝试强制它们与目标表匹配(结果发现它不能)
当您直接从值列表中插入时,它在执行类型推断时知道目标表,然后可以假定任何未类型化的NULL
与相应列匹配。如果您不需要选择
,请使用。
如果您需要它(如使用CTE多次使用输入行),根据用例的详细信息,有一些变通方法
例如,使用完整行时:
INSERT INTO A -- complete rows
SELECT * FROM (
VALUES ((NULL::A).*), (row_1), (row_2), ...
) B
OFFSET 1;
插入到--完整的行中
从中选择*(
值((NULL::A)。*),(第1行),(第2行)。。。
)B
偏移量1代码>
{col_list}
在这种特殊情况下是可选的噪声,因为我们无论如何都需要提供完整的行
详细说明:
如果您不需要
选择,请选择。
如果您需要它(如使用CTE多次使用输入行),根据用例的详细信息,有一些变通方法
例如,使用完整行时:
INSERT INTO A -- complete rows
SELECT * FROM (
VALUES ((NULL::A).*), (row_1), (row_2), ...
) B
OFFSET 1;
插入到--完整的行中
从中选择*(
值((NULL::A)。*),(第1行),(第2行)。。。
)B
偏移量1代码>
{col_list}
在这种特殊情况下是可选的噪声,因为我们无论如何都需要提供完整的行
详细说明:
你好,卢卡斯,看起来不错。但是有了这个json函数,我不知道如何一次插入多行而不重复每行的列名。@Ben我已经更新了答案,将在一次调用中生成行集的函数包括在内:json\u populate\u recordset(…)
谢谢,但是这些重复的列名似乎是多余的,在我的例子中,这些表有十几列,每列都有许多空值。开销似乎有点高。嗨,卢卡斯,看起来不错。但是有了这个json函数,我不知道如何一次插入多行而不重复每行的列名。@Ben我已经更新了答案,将在一次调用中生成行集的函数包括在内:json\u populate\u recordset(…)
谢谢,但是这些重复的列名似乎是多余的,在我的例子中,这些表有十几列,每列都有许多空值。开销似乎有点高。您真的需要选择?在您给出的示例中,插入(…)值…
就足够了。我认为Postgres在没有查询的情况下对未知参数类型不那么挑剔。你真的需要选择?在您给出的示例中,插入(…)值…
就足够了。我认为在没有查询的情况下,Postgres对未知参数类型不那么挑剔。谢谢你的技术。我没有用CTE。但是这种行类型转换看起来非常有用。我希望早点知道。谢谢你的技术指导