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

时间:2011-11-03 19:24:55

标签: sql performance postgresql sqlbulkcopy bulk

目标是:我有一组值进入表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查询要快得多。我想对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,使用外键而不是对列表对象的引用。

2 个答案:

答案 0 :(得分:4)

自己生成ID。

  1. BEGIN交易
  2. 锁定表格
  3. 调用nextval() - 这是您的第一个ID
  4. 使用ID生成您的COPY
  5. 表b
  6. 相同
  7. 使用您的最终ID + 1
  8. 调用setval()
  9. COMMIT交易
  10. 在步骤2中,您可能也希望锁定序列的关系。如果代码调用nextval()并将ID存储在某处,那么它在使用它时可能已经在使用它。

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

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

答案 1 :(得分:0)

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

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

取自here(在c#中,但算法是相同的)

相关问题