【问题标题】:insert into sqlite table with unique column插入具有唯一列的 sqlite 表
【发布时间】:2011-06-04 14:45:23
【问题描述】:

我将值插入到我的表中(来自 python 代码),如下所示:

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

在 c 列上有一个 unique constraint。如果我想在我们为 c 列插入重复值时涵盖这种情况,insert 的常用方法是什么?
我有一些想法

  1. 选择从 t 到列表的所有内容并在插入之前测试该值是否已经存在
  2. try-catch 块
  3. 一些更复杂的 sqlite 语句

你会如何测试它?

谢谢

【问题讨论】:

    标签: python sqlite


    【解决方案1】:

    您可以使用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()'
    

    【讨论】:

    • 谢谢。这比第 1 点在 python 中测试更有效吗?对于我的情况insert or ignore 是理想的。
    • @xralf:sqlite 是用 C 语言编写的,因此允许 sqlite 执行过滤很可能比编写自己的代码在 Python 中执行相同操作更快。 (即使 Python 代码与 C 代码一样快,您仍然必须将整个表加载到 Python 对象中……)但是,由于您询问如何测试此声明,我建议使用 python -mtimeit ...
    【解决方案2】:

    取决于:)

    如果只有一个插入器,则 1 可能是最有效的。

    如果有多个插入器,您必须使用 2 作为 1 以下,您可以测试并且看起来没问题,但是另一个插入器添加了您拥有的 C 值,因此它失败了

    【讨论】:

    • 谢谢,看来只有一个插入器(目前为止,以后可以改)。我将它实现为 1,但是如果我想编写新的插入代码,它(这个测试)会输入很多,而且我不确定测试是否有效,例如列表中有 10000 个值。也许 sqlite 在定义 indeces 方面有一些更复杂的东西。
    猜你喜欢
    • 2021-11-20
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多