使用红移插入行后获取主键

Posted

技术标签:

【中文标题】使用红移插入行后获取主键【英文标题】:Getting the primary key after row insertion using redshift 【发布时间】:2016-02-08 23:46:48 【问题描述】:

我正在使用带有 amazon redshift 的 postgresql 8.0.2,我正在尝试设置一个 INSERT 命令,该命令还返回 PRIMARY KEY

我最初尝试执行以下操作:

with get_connection() as conn:
    with conn.cursor() as cur:
    cur.execute('INSERT INTO orders (my_id, my_amount) \
                 VALUES (%s, %s) RETURNING row_id;', (some_id, some_amount))
    conn.commit()

但是,RETURNING 命令仅适用于 postgresql 8.2 及更高版本。

我看到currval 可能是让它工作的一种可能方法,但我读到它需要一个序列对象。

我正在尝试插入以下架构

CREATE SEQUENCE order_seq;

CREATE TABLE IF NOT EXISTS orders
(
    order_id INTEGER IDENTITY(1,1) PRIMARY KEY DISTKEY, 
)

然后做:

with get_connection() as conn:
    with conn.cursor() as cur:
        cur.execute('INSERT INTO orders (my_id, my_amount) \
                     VALUES (%s, %s);', (some_id, some_amount))
        conn.commit()
        cur.execute('SELECT currval();')
        row_id = cursor.fetchone()[0]

更新:redshift 也不支持序列对象。我觉得这是一个非常基本的过程,但没有简单的方法来获取对当前行的引用。

【问题讨论】:

【参考方案1】:

只需将您的列定义为:

order_id INTEGER PRIMARY KEY DISTKEY

并且随着您创建的序列order_seq 使用它作为插入命令:

cur.execute('INSERT INTO orders (order_id, my_id, my_amount) \
                 VALUES (nextval(''order_seq''), %s, %s);', (some_id, some_amount))

由于您使用的是序列,因此您必须在插入命令中添加字段才能正确使用nextval

要检索当前序列值,请执行以下操作:

cur.execute('SELECT currval(''order_seq'')')
row_id = cursor.fetchone()[0]

我不熟悉您使用的语言,因此您可能需要更改语法以转义我使用的双引号。

nextvalcurrval 的语法类似于:nextval('sequenceName')currval('sequenceName')

因此,如果它不支持sequences,我认为它可以解决您的问题的唯一方法是按照以下步骤操作:

    打开一个事务(这样其他人就不会得到相同的 id) 将您的表的最大 ID(如 select max(order_id) from orders)提取到变量中 在插入时使用此值,因为它是序列。

【讨论】:

正确,但要小心在选择查询中留下尾随 ;;一些司机被他们呛到了。 @JorgeCampos 我想我可能把你弄糊涂了。我正在发送两个值以存储在数据库中。 some_id其实是一笔交易的ID,some_amount是一笔交易的金额。 @Brosef 你来了。由于 nextval 是一个数据库函数,您可以直接在 sql 命令上调用它。 @JorgeCampos conn.commit() 是否应该介于 cur.execute('INSERT') 和 cur.execute('SELECT') 之间? 哦,伙计,redshift 似乎也不支持序列!所以currval不是一个选择。还有其他办法吗?

以上是关于使用红移插入行后获取主键的主要内容,如果未能解决你的问题,请参考以下文章

仅当复合主键尚不存在时,如何批量插入行? [AWS 红移]

使用亚马逊管道的红移副本因缺少主键而失败

使用 JPA 获取最后插入记录的主键

在sqlite中插入时获取主键而不是rowID或通过其rowID获取主键

获取标识主键的最新插入值

mybatis如何获取oracle新插入数据记录的主键?