簡體   English   中英

在PostgreSQL(python)中鏈接到UPDATE的UPSERT語法錯誤

[英]UPSERT syntax error linked to UPDATE in PostgreSQL (python)

我還在學習PostgreSQL。 在我的測試中,我只在psycopg2和現在的asyncpg中使用INSERT語句。 我現在需要在我的測試數據庫中更新數據,而不是替換所有數據。

我正在嘗試在測試表中進行簡單的替換測試,然后再轉移到包含更多數據的開發表。

我想用一個已經在表用戶中的名稱替換CONFLICT中的任何$ 1名稱。 我正在嘗試查詢代碼,它通過asyncpg傳遞給數據庫。 我不斷收到語法錯誤,所以我對如何糾正這些錯誤感到有點迷失。

此查詢的正確語法是什么?

'''INSERT INTO users(name, dob) 
   VALUES($1, $2)
   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($1, $2)
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))

您需要圍繞name的值使用單引號: SET name='TEST'雙引號用於表名或列名。 在您的情況下,您可以刪除users周圍的雙引號。

編輯后:您應該在數據庫控制台中嘗試SQL命令,這與python和async無關。 這是純粹的postgresql語法。

因此,查詢中的第二個問題是您不應在UPDATE之后指定“users”。 這意味着您正在更新同一個表。 所以只是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

你可以測試替換:'''INSERT INTO用戶(名稱,dob)VALUES($ 1,$ 2)ON CONFLICT(名稱)DO UPDATE“users”SET name ='TEST'WHER name = excluded.name'''

通過:“”“INSERT INTO用戶(名稱,dob)VALUES($ 1,$ 2)ON CONFLICT(名稱)DO UPDATE SET name ='TEST'WHER name = excluded.name”“”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM