1

我使用 Python 2.7 和 SQLite3。

这是代码:

#!/usr/bin/env python

import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
c.execute('''CREATE TABLE stocks
             (transctionid text not null collate nocase primary key,
             trans text,
             symbol text not null,
             qty real,
             price real)''')
purchases = [('B1Jan', 'BUY', 'IBM', 1000, 45.00),
             ('C2Jan', 'BUY', 'MSFT', 1000, 72.00),
             ('D3Jan', 'SELL', 'IBM', 500, 53.00),
             ('d3jan', 'SELL', 'IBM', 500, 53.00),
             ('', 'SELL', 'IBM', 500, 53.00),
             ('E5Jan', 'SELL', '', 500, 53.00),
            ]
c.executemany('INSERT OR IGNORE INTO stocks VALUES (?,?,?,?,?)', purchases)
conn.commit()
for row in c.execute('SELECT * FROM stocks ORDER BY price'):
    print row
conn.close()

结果是:

(u'B1Jan', u'BUY', u'IBM', 1000.0, 45.0)
(u'D3Jan', u'SELL', u'IBM', 500.0, 53.0)
(u'', u'SELL', u'IBM', 500.0, 53.0)
(u'E5Jan', u'SELL', u'', 500.0, 53.0)
(u'C2Jan', u'BUY', u'MSFT', 1000.0, 72.0)

INSERT OR IGNORE 仅适用于“PRIMARY KEY”约束。“NOT NULL”约束不起作用。

根据http://www.sqlite.org/lang_conflict.html

对于 INSERT 和 UPDATE 命令,关键字“ON CONFLICT”被替换为“OR”,这样语法读起来更自然。例如,我们用“INSERT OR IGNORE”代替“INSERT ON CONFLICT IGNORE”。... ON CONFLICT 子句适用于 UNIQUE 和 NOT NULL 约束(以及在本节中与 UNIQUE 约束相同的 PRIMARY KEY 约束)。

我预期的结果是:

(u'B1Jan', u'BUY', u'IBM', 1000.0, 45.0)
(u'D3Jan', u'SELL', u'IBM', 500.0, 53.0)
(u'C2Jan', u'BUY', u'MSFT', 1000.0, 72.0)

顺便说一句,我怎么知道哪一行插入成功,哪一行在冲突中被忽略?

4

2 回答 2

2

空字符串不计为NULL,而是 0 长度的字符串。

None如果您希望插入 SQL ,请改用NULL

purchases = [('B1Jan', 'BUY', 'IBM', 1000, 45.00),
             ('C2Jan', 'BUY', 'MSFT', 1000, 72.00),
             ('D3Jan', 'SELL', 'IBM', 500, 53.00),
             ('d3jan', 'SELL', 'IBM', 500, 53.00),
             (None, 'SELL', 'IBM', 500, 53.00),
             ('E5Jan', 'SELL', None, 500, 53.00),
            ]

请参阅文档的SQLite 和 Python 类型部分sqlit3

如果您需要知道行是否插入成功,请一一插入,cursor.execute()然后检查cursor.rowcount.rowcount反映受影响的行数,对于您的调用.executemany(),其NULL值为 rowcount 3,没有关于哪些行成功和哪些行失败的信息。

于 2013-04-18T20:37:08.357 回答
0

''与 NULL 不同。替换''None

如果您想知道哪些行违反了约束,请删除OR IGNORE并处理sqlite3.IntegrityError. 下面的代码示例一一插入行并打印(可以修改为写入文件、记录错误表等),以便您知道哪些值无法插入以及原因:

import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()
c.execute('''CREATE TABLE stocks
             (transctionid text not null collate nocase primary key,
             trans text,
             symbol text not null,
             qty real,
             price real)''')
purchases = [('B1Jan', 'BUY', 'IBM', 1000, 45.00),
             ('C2Jan', 'BUY', 'MSFT', 1000, 72.00),
             ('D3Jan', 'SELL', 'IBM', 500, 53.00),
             ('d3jan', 'SELL', 'IBM', 500, 53.00),
             (None, 'SELL', 'IBM', 500, 53.00),
             ('E5Jan', 'SELL', None, 500, 53.00)]
for purchase in purchases:
    try:
        c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', purchase)
    except sqlite3.IntegrityError as e:
        print "Couldn't insert row {}:\n {}".format(purchase, e)
        pass
conn.commit()
for row in c.execute('SELECT * FROM stocks ORDER BY price'):
    print row
conn.close()
于 2013-04-18T20:37:29.877 回答