tji*_*jim 15 python sqlite python-2.7
我在嵌套循环中的单个sqlite数据库上使用多个游标时遇到问题.我找到了一个适合我的解决方案,但它有限,我没有看到在线记录这个具体问题.我这样发布: - 一个明确的问题/解决方案可用 - 看看是否有更好的解决方案 - 也许我在sqlite3 python模块中发现了一个缺陷
情况就是这样:我的Python应用程序将社交关系数据存储在sqlite中.数据集包括两个表之间的一对多关系:myConnections和sharedConnections.前者每个连接都有一行.sharedConnections表具有0:N行,具体取决于共享的连接数.为了构建结构,我使用嵌套循环.在外部循环中,我访问myConnections中的每一行.在内部循环中,我填充sharedConnections表.代码如下所示:
curOuter = db.cursor()
for row in curOuter.execute('SELECT * FROM myConnections'):
id = row[0]
curInner = db.cursor()
scList = retrieve_shared_connections(id)
for sc in scList:
curInner.execute('''INSERT INTO sharedConnections(IdConnectedToMe, IdShared) VALUES (?,?)''', (id,sc))
db.commit()
Run Code Online (Sandbox Code Playgroud)
结果很奇怪.该sqlite3
表获取前两个记录的重复条目sharedConnections
.他们有点整理.A的连接,B的连接,然后是A,然后是B.在最初的口吃之后,处理是正确的!例:
myConnections
-------------
a
b
c
d
sharedConnections
-------------
a->b
a->c
b->c
b->d
a->b
a->c
b->c
b->d
Run Code Online (Sandbox Code Playgroud)
解决方案不完善.而不是使用迭代器从外循环光标,我myConnections
,然后SELECT
和遍历结果列表.由于我的数据集很小,这没关系.
curOuter = db.cursor()
curOuter.execute('SELECT * FROM myConnections'):
rows = curOuter.fetchall()
for row in rows:
id = row[0]
curInner = db.cursor()
scList = retrieve_shared_connections(id)
for sc in scList:
curInner.execute('''INSERT INTO sharedConnections(IdConnectedToMe, IdShared) VALUES (?,?)''', (id,sc))
db.commit()
Run Code Online (Sandbox Code Playgroud)
你有它.在嵌套循环中对同一sqlite数据库中的不同表使用两个游标似乎不起作用.更重要的是,它不会失败,只会给出奇怪的结果.
所以: - 这真的是最好的解决方案吗?
- 有更好的解决方案吗?
- 这是一个应该解决的缺陷吗?
答案:此时,问题已经提出,有一些讨论,我认为我们已经完成了很多.这是看起来如何:
感谢大家的关注和建议.
最好的问候,-Jim
您可以构建一个行列表以插入内部循环中,然后在循环外部插入cursor.executemany()。这并不能回答多光标问题,但可能是您的解决方法。
curOuter = db.cursor()
rows=[]
for row in curOuter.execute('SELECT * FROM myConnections'):
id = row[0]
scList = retrieve_shared_connections(id)
for sc in scList:
rows.append((id,sc))
curOuter.executemany('''INSERT INTO sharedConnections(IdConnectedToMe, IdShared) VALUES (?,?)''', rows)
db.commit()
Run Code Online (Sandbox Code Playgroud)
最好只从 myConnections 中选择 ID:
curOuter.execute('SELECT id FROM myConnections')
Run Code Online (Sandbox Code Playgroud)