SQLite get id and insert when using executemany

时间:2015-04-29 04:04:11

标签: python sql sqlite python-3.x

I am optimising my code, and reducing the amount of queries. These used to be in a loop but I am trying to restructure my code to be done like this. How do I get the second query working so that it uses the id entered in the first query from each row. Assume that the datasets are in the right order too.

self.c.executemany("INSERT INTO nodes (node_value, node_group) values (?, (SELECT node_group FROM nodes WHERE node_id = ?)+1)", new_values)
#my problem is here
new_id = self.c.lastrowid
connection_values.append((node_id, new_id))
#insert entry
self.c.executemany("INSERT INTO connections (parent, child, strength) VALUES (?,?,1)", connection_values)

These queries used to be a for loop but were taking too long so I am trying to avoid using a for loop and doing the query individually. I believe their might be a way with combining it into one query but I am unsure how this would be done.

1 个答案:

答案 0 :(得分:0)

您需要一次插入一行或读回由SQLite的ID分配逻辑选择的rowid;如Autoincrement in SQLite中所述,无法保证生成的ID将是连续的,并且尝试在客户端代码中猜测它们是一个坏主意。

如果您的程序是单线程的,则可以隐式执行此操作:

在表定义中设置AUTOINCREMENT关键字。这将保证任何生成的行ID都将高于当前表中显示的任何行ID。

  1. 在第一个语句之前,确定表中使用的最高ROWID。

    oldmax ←执行("SELECT max(ROWID) from nodes")。

  2. 像以前一样执行第一次插入。

  3. 回读用select语句实际分配的行ID:

    NewNodes ←执行("SELECT ROWID FROM nodes WHERE ROWID > ? ORDER BY ROWID ASC" oldmax )。

  4. 通过组合connection_values中的父ID和 NewNodes 中的子ID来构造new_values数组。

  5. 像以前一样执行第二次插入。

  6. 这可能比原始代码快,也可能不快; AUTOINCREMENT可能会降低性能,如果没有实际进行实验,就无法分辨。

    如果您的程序从多个线程写入nodes,您需要使用互斥锁来保护此算法,因为它对多个并发写入器都不起作用。