У меня были проблемы с использованием нескольких курсоров в одной базе данных sqlite во вложенном цикле. Я нашел решение, которое работает для меня, но оно ограничено, и я не видел этой конкретной проблемы, задокументированной в Интернете. Я публикую это так:
- Доступна ясная проблема/решение
- Чтобы увидеть, есть ли лучшее решение
- Возможно, я обнаружил дефект в модуле Python
sqlite3
Мое приложение 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()
Результат странный. Таблица sharedConnections
получает повторяющиеся записи для первых двух записей в myConnections
. Они немного сопоставлены. Как соединения, соединения Bs, затем A и B снова. После первоначального заикания обработка идет правильно! Пример:
myConnections
-------------
a
b
c
d
sharedConnections
-------------
a->b
a->c
b->c
b->d
a->b
a->c
b->c
b->d
Решение несовершенно. Вместо использования итератора из курсора внешнего цикла, я SELECT
, затем fetchall()
и перебираю результирующий список. Так как мой набор данных довольно маленький, это нормально.
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()
Там у вас есть это. Использование двух курсоров для разных таблиц в одной и той же базе данных sqlite во вложенном цикле, похоже, не работает. Более того, он не дает сбоя, он просто дает странные результаты.
- Это действительно лучшее решение?
- Есть ли лучшее решение?
- Это дефект, который следует устранить?