2011-11-03 64 views
2

目标是这样的:我有一组值来进入表A,并将一组值写入表B。进入B的参考值的值为A(通过外键),所以在插入A值后,我需要知道在插入B值时如何引用它们。我需要这个尽可能快。postgresql:如何获取用批量copy_from插入的行的主键?

我做了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,使用外键,而不是到列表对象的引用。

回答

4

自己生成ID。

  1. BEGIN TRANSACTION
  2. 锁表
  3. 调用NEXTVAL() - 这是你的第一个ID
  4. 生成的ID复印到位
  5. 同为表B
  6. 调用SETVAL()与您的最终ID + 1
  7. COMMIT交易

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

稍微偏离主题的事实:如果您有大量后端插入大量内容,则可以设置“缓存”设置。这样可以增加计数器的大小。

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

+0

最后我做类似的措施。我有两个id字段:一个batch_id和一个within_batch_id。我用'nextval'获得了batch_id,我刚刚生成了自己的within_batch_id。然后我用batch_id做了一个选择以获得我刚插入的内容,并将它们与within_batch_id对齐。谢谢! – Claudiu

0

其实你可以采取不同的方式,你需要的是:

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

here拍摄(在C#中,但算法中是一样的)