postgresql:如何获取使用批量copy_from插入的行的主键?

bulk performance postgresql sql sqlbulkcopy

目标是:我有一组值进入表A ,一组值进入表B进入值B参考值A (通过外键),那么在插入后A值,我需要知道如何在插入时引用它们B值。我需要尽可能快。

我使用批量复制插入B值:

def bulk_insert_copyfrom(cursor, table_name, field_names, values):
    if not values: return

    print "bulk copy from prepare..."
    str_vals = "\n".join("\t".join(adapt(val).getquoted() for val in cur_vals) for cur_vals in values)
    strf = StringIO(str_vals)
    print "bulk copy from execute..."
    cursor.copy_from(strf, table_name, columns=tuple(field_names))

这比执行INSERT VALUES ... RETURNING id快得多INSERT VALUES ... RETURNING id查询。我想对A值做同样的事情,但我需要知道插入行的id

有没有办法以这种方式执行批量复制,但要获取插入的行的id字段(主键),以便我知道哪个id与哪个value相关联?

如果没有,那么实现目标的最佳方法是什么?

编辑:请求的示例数据:

a_val1 = [1, 2, 3]
a_val2 = [4, 5, 6]
a_vals = [a_val1, a_val2]

b_val1 = [a_val2, 5, 6, 7]
b_val2 = [a_val1, 100, 200, 300]
b_val3 = [a_val2, 9, 14, 6]
b_vals = [b_val1, b_val2, b_val3]

我想插入a_vals ,然后插入b_vals ,使用外键而不是对列表对象的引用。

一般承认的答案

自己生成ID。

  1. BEGIN交易
  2. 锁表a
  3. 调用nextval() - 这是你的第一个ID
  4. 使用ID生成您的COPY
  5. 表b相同
  6. 使用您的最终ID + 1调用setval()
  7. COMMIT事务

在第2步,您可能也想锁定序列的关系。如果代码调用nextval()并将ID存储在某处,那么它在使用它时可能已经在使用它。

稍微偏离主题的事实:如果你有很多后端进行大量插入,你可以设置一个“缓存”设置。这会以块为单位递增计数器。

http://www.postgresql.org/docs/9.1/static/sql-createsequence.html


热门答案

实际上你可以用不同的方式做,你需要的是:

  • 开始交易
  • 使用相同(或几乎相同)的模式创建临时表
  • COPY数据COPY到该临时表
  • 执行regullar INSERT INTO .. FROM temp_table ... RETURNING id, other_columns
  • 承诺

取自这里 (在c#,但算法是相同的)




许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因