UPSERT 语法错误链接到 PostgreSQL 中的更新 (python)
UPSERT syntax error linked to UPDATE in PostgreSQL (python)
我还在学习 PostgreSQL。在我的测试期间,我只在 psycopg2 和现在的 asyncpg 中使用了 INSERT 语句。我现在需要更新我的测试数据库中的数据,而不是替换所有数据。
我目前正尝试在测试 table 中进行简单的替换测试,然后再转向开发 table 以获取更多数据。
我想用 table 用户中已有的名称替换冲突中的任何 $1 名称。我正在尝试通过 asyncpg 传递给数据库的查询代码。我不断收到语法错误,所以我对如何更正这些错误有些迷茫。
此查询的正确语法是什么?
'''INSERT INTO users(name, dob)
VALUES(, )
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
更新:
我在使用 asyncpg 时收到此错误消息:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near ""users""
我在使用 psycopg2 时收到此错误消息:
psycopg2.ProgrammingError: syntax error at or near ""users""
这是我一直用来执行 INSERT 的 asyncpg 代码:
async def insert_new_records(self, sql_command, data):
print (sql_command)
async with asyncpg.create_pool(**DB_CONN_INFO, command_timeout=60) as pool:
async with pool.acquire() as conn:
try:
stmt = await conn.prepare(sql_command)
async with conn.transaction():
for value in data:
async for item in stmt.cursor(*value):
pass
finally:
await pool.release(conn)
test_sql_command = '''
INSERT INTO users(name, dob)
VALUES(, )
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
# The name 'HELLO WORLD' exists in the table, but the other name does not.
params = [('HELLO WORLD', datetime.date(1984, 3, 1)),
('WORLD HELLO', datetime.date(1984, 3, 1))]
loop = asyncio.get_event_loop()
loop.run_until_complete(db.insert_new_records(test_sql_command, params))
名称的值需要用单引号引起来:SET name='TEST'
双引号用于 table 或列名。在您的情况下,您可以删除 users
.
周围的双引号
编辑后:
您真的应该在数据库控制台中尝试您的 SQL 命令,这与 python 或异步无关。这是纯 postgresql 语法。
因此,您查询中的第二个问题是您不应在 UPDATE 后指定 "users"。这意味着您正在更新相同的 table。所以 DO UPDATE SET...
就好了。
然后,你会得到column reference "name" is ambiguous
。你应该写DO UPDATE SET name='TEST'
。您已经在更新行 where name=excluded.name
。我不是 100% 清楚你想做什么。因此,如果您插入一行一次,它会像往常一样插入。如果第二次插入,名称将替换为 'TEST'。 excluded 关键字允许您访问尝试的插入值。因此,例如,如果您想在尝试插入现有名称时更新 last_access
列,您可以编写 ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
.
你可以测试
代替 :
'''插入用户(姓名,出生日期)
价值(1 美元,2 美元)
关于冲突(姓名)
做
更新 "users"
设置名称 = 'TEST'
其中名称 = excluded.name '''
来自 :
“”“插入用户(姓名,出生日期)
价值(1 美元,2 美元)
关于冲突(姓名)
做
更新
设置名称 = 'TEST'
其中名称 = excluded.name """
我还在学习 PostgreSQL。在我的测试期间,我只在 psycopg2 和现在的 asyncpg 中使用了 INSERT 语句。我现在需要更新我的测试数据库中的数据,而不是替换所有数据。
我目前正尝试在测试 table 中进行简单的替换测试,然后再转向开发 table 以获取更多数据。
我想用 table 用户中已有的名称替换冲突中的任何 $1 名称。我正在尝试通过 asyncpg 传递给数据库的查询代码。我不断收到语法错误,所以我对如何更正这些错误有些迷茫。
此查询的正确语法是什么?
'''INSERT INTO users(name, dob)
VALUES(, )
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
更新:
我在使用 asyncpg 时收到此错误消息:
asyncpg.exceptions.PostgresSyntaxError: syntax error at or near ""users""
我在使用 psycopg2 时收到此错误消息:
psycopg2.ProgrammingError: syntax error at or near ""users""
这是我一直用来执行 INSERT 的 asyncpg 代码:
async def insert_new_records(self, sql_command, data):
print (sql_command)
async with asyncpg.create_pool(**DB_CONN_INFO, command_timeout=60) as pool:
async with pool.acquire() as conn:
try:
stmt = await conn.prepare(sql_command)
async with conn.transaction():
for value in data:
async for item in stmt.cursor(*value):
pass
finally:
await pool.release(conn)
test_sql_command = '''
INSERT INTO users(name, dob)
VALUES(, )
ON CONFLICT (name)
DO
UPDATE "users"
SET name = 'TEST'
WHERE name = excluded.name '''
# The name 'HELLO WORLD' exists in the table, but the other name does not.
params = [('HELLO WORLD', datetime.date(1984, 3, 1)),
('WORLD HELLO', datetime.date(1984, 3, 1))]
loop = asyncio.get_event_loop()
loop.run_until_complete(db.insert_new_records(test_sql_command, params))
名称的值需要用单引号引起来:SET name='TEST'
双引号用于 table 或列名。在您的情况下,您可以删除 users
.
编辑后: 您真的应该在数据库控制台中尝试您的 SQL 命令,这与 python 或异步无关。这是纯 postgresql 语法。
因此,您查询中的第二个问题是您不应在 UPDATE 后指定 "users"。这意味着您正在更新相同的 table。所以 DO UPDATE SET...
就好了。
然后,你会得到column reference "name" is ambiguous
。你应该写DO UPDATE SET name='TEST'
。您已经在更新行 where name=excluded.name
。我不是 100% 清楚你想做什么。因此,如果您插入一行一次,它会像往常一样插入。如果第二次插入,名称将替换为 'TEST'。 excluded 关键字允许您访问尝试的插入值。因此,例如,如果您想在尝试插入现有名称时更新 last_access
列,您可以编写 ON CONFLICT (name) DO UPDATE last_access=excluded.last_access
.
你可以测试 代替 : '''插入用户(姓名,出生日期) 价值(1 美元,2 美元) 关于冲突(姓名) 做 更新 "users" 设置名称 = 'TEST' 其中名称 = excluded.name '''
来自 : “”“插入用户(姓名,出生日期) 价值(1 美元,2 美元) 关于冲突(姓名) 做 更新 设置名称 = 'TEST' 其中名称 = excluded.name """