使用 Python 中的 psycopg2 将插入行的自动 ID 获取到 Redshift table

Get the auto id for inserted row into Redshift table using psycopg2 in Python

我正在从 Python 2.7 使用 [=23] 将记录插入 Amazon Redshift table =]psycopg2 库,我想取回插入行的自动生成主 ID。

我已尝试使用 google 搜索在此处或其他网站上找到的常用方法,例如:

conn=psycopg2.connect(conn_str)
conn.autocommit = True

sql = "INSERT INTO schema.table (col1, col2) VALUES (%s, %s) RETURNING id;"

cur = conn.cursor()
cur.execute(sql,(val1,val2))
id = cur.fetchone()[0]

我在 cur.execute 行收到一个错误:

ProgrammingError: syntax error at or near "RETURNING"

有人知道如何解决这个问题或完成同样的事情吗?

I have to use psycopg2 in my code

目前无法使用 Redshift,因为它不支持通过 RETURNING 语法返回最后插入的 ID。您可能需要做的是在交易中使用 SELECT MAX(id) FROM schema.table;,这可能不是您想要听到的,但似乎是您在 Redshift 的当前状态下可以做的最好的事情。

如果您知道如何唯一地找到没有 ID 的行,您也可以在 select 中查询 ID。

目前Redshift还不支持RETURNING语法,我在这里找不到满意的答案。所以我发布了一个通用的解决方案,以防有人需要它。

此解决方案的唯一假设是您知道刚刚插入了多少条记录。假设 x 是插入的记录数,您可以 运行 这个查询:

SELECT id 
FROM table 
ORDER BY id DESC
LIMIT {x}

非常重要!您必须 运行 此查询连同在 同一事务 中插入的查询。不然不行。

您可以使用以下查询从 redshift 获取最后插入的 ID。

SELECT top 1 id from sampletable where created < Getdate() order by created desc;

其中 'id' 是您感兴趣的字段,'created' 是包含日期时间信息的字段。

使用创建的日期时间信息的原因是,如果 table 用于批量插入,则有可能获得 ID 为 1、33、35、56、103 等顺序的记录..... 在上面的场景中,使用 max(id) 不会按预期工作。 因为最后插入的 ID 可以是之前未插入的任何数字。

假设您没有(可能)插入重复项,您可以使用 python 执行此操作。我假设您提供的代码在循环中;循环的细节无关紧要,但将 # before the loop 部分放在循环之前。

# before the loop
# you probably have a list or dict of values that you're inputting. Re-use that if you can; if you can't, create a dict
sample_dict = {}
# end before the loop

/* existing code */
conn=psycopg2.connect(conn_str)
conn.autocommit = True

# use this query instead of your current one (just remove the RETURNING clause)
ins_sql = "INSERT INTO schema.table (col1, col2) VALUES (%s, %s);"

# this query will get the id of those last added values
sel_sql = "SELECT id FROM schema.table WHERE col1 = %s AND col2 = %s ORDER BY id DESC LIMIT 1;"

cur = conn.cursor()
cur.execute(ins_sql,(val1,val2))

# new stuff here!
cur.execute(sel_sql,(val1,val2))
id = cur.fetchone()[0]
sample_dict[val1 + '|' + val2] = id

注意事项:

  1. 我还没有测试过这个确切的脚本
  2. 如果您要插入重复值,这可能不起作用
  3. 您没有清理您的输入或使用准备好的语句(不能 100% 确定这是一个选项,TBH)
  4. 你比我更了解你的数据库和代码结构;利用这些知识
  5. 这不是最有效的解决方案,但应该满足您的需求。