2011-11-03 65 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#中,但算法中是一樣的)