使用Python中的psycopg2获取插入行的自动id到Redshift表中

时间:2017-04-05 19:27:00

标签: python python-2.7 amazon-web-services amazon-redshift psycopg2

我正在使用 psycopg2 库从 Python 2.7 中将记录插入到 Amazon Redshift 表中,我想恢复自动生成插入行的主要ID。

我尝试过常用的方法,可以在这里或使用谷歌搜索的其他网站找到,例如:

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"

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

  

我必须在我的代码中使用 psycopg2

5 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

此刻,Redshift仍然不支持RETURNING语法,我在这里找不到令人满意的答案。因此,我发布了一个通用解决方案,以防万一有人需要它。

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

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

非常重要!您必须在同一笔交易中与插入查询一起运行此查询。否则,它将无法正常工作。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

其中“ id”是您感兴趣的字段,“创建”是具有日期时间信息的字段。

使用创建的日期时间信息的原因是,如果该表用于批量插入,则有可能具有ID的记录是连续的,例如1,33,35,56,103等。 在上述情况下,使用max(id)无法按预期工作。 因为最后插入的ID可以是之前未插入的任何数字。

答案 4 :(得分:0)

假设您没有(可能)插入重复项,则可以使用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. 这不是最有效的解决方案,但它应该能满足您的需求。