使用 Psycopg2 插入 table:冲突时不做任何事情

Inserting into a table with Psycopg2: Do Nothing on Conflict

您好,这是我当前的查询:

        query = sql.SQL("insert into {schema}.{table} ({fields}) values ({placeholder}) ON CONFLICT DO UPDATE SET {updates}").format(
        schema=sql.Identifier(self.schema),
        table=sql.Identifier(tbl_name),
        fields=sql.SQL(', ').join(sql.Identifier(field_name) for field_name in column_names_lst),
        placeholder=sql.SQL(', ').join(sql.Placeholder() for field_value in column_data_lst),
        updates = ', '.join(f"{column_name} = '{column_value}'" for column_name, column_value
                               in tbl_data.items())
    )

它在添加 ON CONFLICT DO UPDATE 部分和添加更新参数之前工作,但从那时起我需要将一些列作为一些目标表的主键。

我的语法有问题,但似乎无法调试它,出现 TypeError:

Composed elements must be Composable, got...

任何见解都会有所帮助,这对我来说是一个新图书馆。

updates 只是一个组合字符串,使用 psycopg2.sql:

可能会更好
schema = 'public'
tbl_name = 'testTable'
column_names_lst = ['column_1', 'column_2', 'column_3']
column_data_lst = (1, 2, 3)
tbl_data = dict(zip(column_names_lst, column_data_lst))

query = sql.SQL(
    "insert into {schema}.{table} ({fields}) values ({placeholder}) ON CONFLICT DO UPDATE SET {updates}"
).format(
    schema=sql.Identifier(schema),
    table=sql.Identifier(tbl_name),
    fields=sql.SQL(', ').join(
        sql.Identifier(field_name) for field_name in column_names_lst
    ),
    placeholder=sql.SQL(', ').join(
        sql.Placeholder() for field_value in column_data_lst
    ),
    updates=sql.SQL(', ').join(
        [
            sql.SQL("{}={}").format(sql.Identifier(k), sql.Placeholder())
            for k in column_names_lst
        ]
    )
)

print(query.as_string(cur))
# duplicate values in order to fill UPDATE values
allValues = column_data_lst + column_data_lst
print(cur.mogrify(query, allValues).decode('utf-8'))

输出:

insert into "public"."testTable" ("column_1", "column_2", "column_3") values (%s, %s, %s) ON CONFLICT DO UPDATE SET "column_1"=%s, "column_2"=%s, "column_3"=%s
insert into "public"."testTable" ("column_1", "column_2", "column_3") values (1, 2, 3) ON CONFLICT DO UPDATE SET "column_1"=1, "column_2"=2, "column_3"=3