2011-06-04 31 views
6

我值插入我的表(從Python代碼)如下:插入到SQLite表具有獨特的列

cur.execute("insert into t(a, b, c) values (?, ?, ?)", (a, b, c)) 

有在列c一unique constraint。如果我想介紹一下我們爲c列插入重複值的情況,那麼insert的常見方法是什麼?
我有一些想法

  1. 選擇一切從T到列出並插入如果該值已經存在之前測試
  2. try-catch塊
  3. 一些更復雜的SQLite聲明

如何你會測試它嗎?

謝謝

回答

11

你可以使用INSERT OR REPLACE具有唯一約束更新行, 或INSERT OR IGNORE忽略插入其具有唯一約束衝突:

import sqlite3 

def insert_or_replace(): 
    # https://sqlite.org/lang_insert.html 
    connection=sqlite3.connect(':memory:') 
    cursor=connection.cursor() 
    cursor.execute('CREATE TABLE foo (bar INTEGER UNIQUE, baz INTEGER)') 
    cursor.execute('INSERT INTO foo (bar,baz) VALUES (?, ?)',(1,2)) 
    cursor.execute('INSERT OR REPLACE INTO foo (bar,baz) VALUES (?, ?)',(1,3)) 
    cursor.execute('SELECT * from foo') 
    data=cursor.fetchall() 
    print(data) 
    # [(1, 3)] 


def on_conflict(): 
    # https://sqlite.org/lang_insert.html 
    connection=sqlite3.connect(':memory:') 
    cursor=connection.cursor() 
    cursor.execute('CREATE TABLE foo (bar INTEGER UNIQUE, baz INTEGER)') 
    cursor.execute('INSERT INTO foo (bar,baz) VALUES (?, ?)',(1,2)) 
    cursor.execute('INSERT OR IGNORE INTO foo (bar,baz) VALUES (?, ?)',(1,3)) 
    cursor.execute('SELECT * from foo') 
    data=cursor.fetchall() 
    print(data) 
    # [(1, 2)]  

insert_or_replace() 
on_conflict() 

這些sqlite的命令可能比編寫Python代碼做同樣的事情更快,但要測試這一點,你可以使用Python的timeit模塊測試var的速度實現。例如,您可以運行

python -mtimeit -s'import test' 'test.insert_or_replace()' 

python -mtimeit -s'import test' 'test.filter_nonunique_rows_in_Python()' 

python -mtimeit -s'import test' 'test.insert_with_try_catch_blocks()' 
+0

謝謝。這比python中的第1點測試更有效率嗎?對於我的情況'插入或忽略'是理想的。 – xralf 2011-06-04 16:18:03

+1

@xralf:sqlite是用C語言編寫的,因此允許sqlite執行過濾的速度最快可能比編寫自己的代碼在Python中執行相同的事情更快。 (即使Python代碼與C代碼一樣快,您仍然必須將整個表加載到一個Python對象中......)但是,由於您詢問了如何測試此聲明,我建議使用'python -mtimeit ...'。 – unutbu 2011-06-04 16:27:10

1

取決於:)

如果只有一個插入了1可能是最有效的。

如果有多個插入器必須使用2作爲下1你可以測試,似乎不錯,但另一個插件增加你的C值,因此無法

+0

謝謝,這似乎只會有一個插件(到目前爲止,可以在未來改變)。我已經將它實現爲1,但是如果我想編寫新的插入代碼,這是(此測試)相當多的輸入,我不確定測試是否有效。列表中有10000個值。也許sqlite在定義indeces方面有更復雜的東西。 – xralf 2011-06-04 15:26:13