PostgreSQL ON CONFLICT错误插入列EXCLUDED.column_name与psycopg2.sql



我将psycopg2与psycopg2.sql.一起使用

import psycopg2
from psycopg2 import sql

我重新编写了一些静态sql代码,通过使用sql使其更加动态。占位符和sql。标识符。

然而,即使没有冲突,我也会得到一个错误:

插入表时出错:column"排除。域名"不存在

我的sql查询如下所示:

query = sql.SQL("insert into dns ({}) values ({}) "
"ON CONFLICT ({}) "
"DO UPDATE SET ({}) = ({}) "
"WHERE {} >= ({});").format(
sql.SQL(', ').join(map(sql.Identifier, dns_cols)),
sql.SQL(', ').join(sql.Placeholder() * len(dns_vals)),
sql.SQL(', ').join(map(sql.Identifier, conflict_cols)),
sql.SQL(', ').join(map(sql.Identifier, dns_cols)),
sql.SQL(', ').join(map(sql.Identifier, excluded_names)),
sql.Identifier('EXCLUDED.updated_date_time'),
sql.Identifier('dns.updated_date_time')
)

mogrify打印出以下内容:

b'insert into dns ("domain_name", "tld", "subdomain", "https", "cf_url", "updated_date_time") values ('example', 'org', '', false, 'http://example.org', '2018-12-06 23:12:00') ON CONFLICT ("domain_name", "tld", "subdomain") DO UPDATE SET ("domain_name", "tld", "subdomain", "https", "cf_url", "updated_date_time") = ("EXCLUDED.domain_name", "EXCLUDED.tld", "EXCLUDED.subdomain", "EXCLUDED.https", "EXCLUDED.cf_url", "EXCLUDED.updated_date_time") WHERE "EXCLUDED.updated_date_time" >= ("dns.updated_date_time");'

dns_colsexcluded_namesdns_vals都是列表,它们的值似乎在mogrify打印输出中显示得很好。

我从来没有需要创建EXCLUDED列,当";关于冲突";被触发。

使用psycopg2.sql占位符时,如何引用EXCLUDED列

您正在引用一个名称包含文字句点的非限定列。如果你想引用这个,你必须分别引用这两个部分,而不是一起引用。此外,如果你引用它,EXCLUDED必须用小写(我有点惊讶它在引用时能起作用(。

"excluded"."domain_name"

最好的方法可能是将EXCLUDED硬编码到查询字符串中,并将其从sql中删除。标识符调用:

"DO UPDATE SET ({}) = (EXCLUDED.{}) "
...
sql.Identifier('updated_date_time'),

最新更新