简体   繁体   English

SQLite获取ID并在使用executemany时插入

[英]SQLite get id and insert when using executemany

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. 如何使第二个查询正常工作,以便它使用在每一行的第一个查询中输入的ID。 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. 这些查询曾经是for循环,但是花费的时间太长,所以我试图避免使用for循环并单独进行查询。 I believe their might be a way with combining it into one query but I am unsure how this would be done. 我相信他们可能是将其合并为一个查询的一种方式,但是我不确定如何实现。

You will need to either insert rows one at a time or read back the rowids that were picked by SQLite's ID assignment logic; 您将需要一次插入一行,或者读回SQLite的ID分配逻辑所选择的rowid。 as documented in Autoincrement in SQLite , there is no guarantee that the IDs generated will be consecutive and trying to guess them in client code is a bad idea. SQLite的自动增量中所述 ,不能保证生成的ID是连续的,并且尝试在客户端代码中猜测它们是一个坏主意。

You can do this implicitly if your program is single-threaded as follows: 如果您的程序是单线程的,则可以隐式地执行此操作:

Set the AUTOINCREMENT keyword in your table definition. 在表定义中设置AUTOINCREMENT关键字。 This will guarantee that any generated row IDs will be higher than any that appear in the table currently. 这将确保任何生成的行ID都将高于当前表中显示的任何行ID。

  1. Immediately before the first statement, determine the highest ROWID in use in the table. 在第一条语句之前,立即确定表中使用的最高ROWID。

    oldmax ← Execute( "SELECT max(ROWID) from nodes" ). oldmax ←Execute( "SELECT max(ROWID) from nodes" )。

  2. Perform the first insert as before. 像以前一样执行第一个插入。

  3. Read back the row IDs that were actually assigned with a select statement: 读回实际分配给选择语句的行ID:

    NewNodes ← Execute( "SELECT ROWID FROM nodes WHERE ROWID > ? ORDER BY ROWID ASC" , oldmax ) . NewNodes ←Execute( "SELECT ROWID FROM nodes WHERE ROWID > ? ORDER BY ROWID ASC"oldmax )。

  4. Construct the connection_values array by combining the parent ID from new_values and the child ID from NewNodes . 通过组合new_values的父ID和NewNodes的子ID来构造connection_values数组。

  5. Perform the second insert as before. 像以前一样执行第二次插入。

This may or may not be faster than your original code; 这可能会或可能不会比您的原始代码快; AUTOINCREMENT can slow down performance, and without actually doing the experiment there's no way to tell. AUTOINCREMENT可能会降低性能,并且没有实际进行实验就无法说明。

If your program is writing to nodes from multiple threads, you'll need to guard this algorithm with a mutex as it will not work at all with multiple concurrent writers. 如果您的程序正在从多个线程向nodes写入数据,则您需要使用互斥量来保护该算法,因为该算法根本无法在多个并发写入器中使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM