插入唯一列到SQLite表中

7 投票
2 回答
11307 浏览
提问于 2025-04-16 18:57

我正在通过Python代码向我的表格中插入值,代码如下:

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

在列c上有一个唯一约束,这意味着在这个列里不能有重复的值。如果我想在插入c列的重复值时处理这种情况,有什么常见的方法呢?
我有一些想法:

  1. 从表t中选择所有内容,先列出来,然后在插入之前检查这个值是否已经存在
  2. 使用try-catch块来处理可能出现的错误
  3. 使用一些更复杂的sqlite语句

你会怎么测试呢?

谢谢!

2 个回答

1

这要看情况 :)

如果只有一个插入器,使用1可能是最有效的选择。

但如果有多个插入器,就得用2,因为如果只用1,可能测试的时候看起来没问题,但如果再加一个插入器,就会把你已有的C值加上去,这样就会出错了。

14

你可以使用 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 模块来测试不同实现的速度。比如,你可以运行

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()'

撰写回答