【问题标题】:How to fix "syntax error at or near "$1" with asyncpg API如何使用 asyncpg API 修复“$1”处或附近的“语法错误”
【发布时间】:2019-01-28 02:51:08
【问题描述】:

我正在尝试通过 asyncpg API 使用查询参数在 postgresql 数据库的表中插入值。 我这样创建了我的表:

CREATE TABLE my_table
(
    cat BIGINT,
    roles BIGINT ARRAY
);

我已经尝试像这样直接在 BIGINT 中转换参数:$1:BIGINT 但我得到了同样的错误

await connection.execute('''
        INSERT INTO my_table(cat, roles)
        VALUES($1, $2)
        ON CONFLICT ($1)
        DO UPDATE SET roles = array_append(roles, $2)
        ''', cat, roles)

cat 是一个 int,角色是一个 int 数组

应该在 my_table 中插入 cat 和角色,但我得到了错误:syntax error at or near "$1"

我提供数据库的日志以防万一

2019-01-26 21:01:22 UTC:172.31.36.115(37598):Barbote@Barbotedb:[15082]:ERROR: syntax error at or near "$1" at character 111
2019-01-26 21:01:22 UTC:172.31.36.115(37598):Barbote@Barbotedb:[15082]:STATEMENT: 
INSERT INTO "429792212016955423"(cat, roles)
VALUES($1 $2)
ON CONFLICT ($1)
DO UPDATE SET roles = array_append(roles, $2);

【问题讨论】:

  • 看来你的 await connection.execute 行有错字(execute 拼写为 exceute。)我也认为你会想要 ON CONFLICT (cat) 因为这与位置参数无关你赋予价值。
  • 我在复制代码时犯了一个错误。我更改了 ON CONFLICT 部分,现在出现了一个新错误 column reference "roles" is ambigious
  • roles 可以包含重复项吗?
  • 我只需要这样写my_table.roles我现在又遇到了另一个错误there is no unique or exclusion constraint matching the ON CONFLICT specification我应该编辑我的帖子还是创建一个新帖子?

标签: python postgresql asyncpg


【解决方案1】:

您需要一个主键(或唯一列)才能使用ON CONFLICT,因此您必须将表定义为

CREATE TABLE my_table
(
    cat BIGINT PRIMARY KEY, -- !!
    roles BIGINT ARRAY
);

roles 列在UPDATE 中不明确,请通过指定表名来修复它:

await connection.execute('''
        INSERT INTO my_table(cat, roles)
        VALUES($1, $2)
        ON CONFLICT (cat)
        DO UPDATE SET roles = array_cat(my_table.roles, $2)
        ''', cat, roles)

请注意,函数array_append() 将元素附加到数组中。您可以改用array_cat()。但是,它可能会导致单个数组中的元素重复。如果你的目标是在数组中有不同的元素,你应该在 Postgres 中定义一个自定义函数:

create or replace function public.array_merge(anyarray, anyarray)
returns anyarray language sql
as $function$
    select 
        array(
            select unnest($1)
            union
            select unnest($2)
            order by unnest
        )
$function$;

并使用它来代替array_cat()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 2020-02-14
    • 2014-07-10
    • 1970-01-01
    • 2015-03-10
    相关资源
    最近更新 更多