1

我正在尝试通过 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 数组

应该将 cat 和角色插入 my_table 但我刚刚收到错误: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);
4

1 回答 1

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().

于 2019-01-27T18:51:08.960 回答