我为我的表设置了一个主键。现在我想在executemany Insert时自动跳过重复的raw。 我该怎么办?这是我的代码和评论。谢谢你们。
cmd = \
'''
CREATE TABLE test(
id INTEGER PRIMARY KEY NOT NULL,
value INTEGER
)
'''
c.execute(cmd)
# now we have key = 1,2,3,4
c.executemany("INSERT INTO test VALUES (%s,%s)", [(1,100),
(3,100),
(2,100),
(4,100),])
# I want script automatically skip repeated row (1,200)
# if I add a try, except here, only the (5, 100) has been inserted
# because script jump out when exception raised
c.executemany("INSERT INTO testVALUES (%s, %s)", [(5,100),
(1,200),
(6,100)])
答案 0 :(得分:0)
如果您想使用这种INSERT
语法,我建议您使用executemany
,在循环内使用execute
,并在每次commit
之后使用commit
一个(因为如果你没有conn
,你将在异常发生后丢失以前插入的项目。)
类似(for item_tuple in [(1,100), (3,100), (2,100), (4,100)]:
try:
c.execute("INSERT INTO test VALUES (%s,%s)", item_tuple[0],
item_tuple[1])
conn.commit()
except Exception as e:
print "failed to insert: {0}".format(e)
conn.rollback()
# continue on to next item
是你的连接对象):
rollback
这样,你可以继续,吞下(并打印)异常(如果需要,你可以使用正则表达式来搜索异常文本以获得更窄的字符串,这样你就不会吞下每个异常,因为这样做在某些情况下可能是不受欢迎的),然后commit
这样你就可以继续使用连接了(否则你会得到一个关于尝试使用与中止事务的连接的错误)。 / p>
另一个选项,不一定要求您对每个项目INSERT
:
你可以使用SELECT
形式作为输入,for item_tuple in [(1,100), (3,100), (2,100), (4,100)]:
c.execute("INSERT INTO test VALUES (%s,%s)
SELECT %s, %s
WHERE NOT EXISTS (SELECT 1
FROM test
WHERE value = %s
)",
item_tuple[0], item_tuple[1], item_tuple[0],
item_tuple[1], item_tuple[1])
语句作为输入,你可以构造它以便选择所需的值,但检查它们是否已经存在,所以如果是,则select的结果为空集,并且不会插入任何内容。 (由于 MVCC ,这可能会在多个连接和事务的情况下出现问题,但如果您是唯一一个为了此检查而插入表中的人,则应该没问题)。
所以,像这样:
{{1}}