Используйте имена, чтобы получить более информативные сообщения об ошибках. Например, я намеренно пропустил запятую с этим:
cur.execute("select ? ?,?", (1,2,3))
SQLError: near "?": syntax error
Теперь с именами:
cur.execute("select :1 :2,:3", (1,2,3))
SQLError: near ":2": syntax error
Если у вас много привязок, я бы порекомендовал вам переключиться на именованный стиль привязок и передать словарь для самих привязок.
cur.execute("select :artist, :painting, :date",
{"artist": "Monster", "painting": "The Duck", "date": "10/10/2010" })
Вы можете использовать привязки только для значений, но не для имен столбцов или таблиц. Есть несколько возможных подходов. Хотя SQLite поддерживает произвольные имена столбцов / таблиц, вы можете потребовать, чтобы они представляли собой только буквенно-цифровой текст ASCII. Если вы хотите быть менее строгим, вам нужно процитировать имена. Используйте квадратные скобки вокруг имени с двойными кавычками и двойные кавычки вокруг имени с квадратными скобками. Имя не может иметь обоих.
Альтернатива всему, что использует механизм авторизации. См. Connection.setauthorizer для API и указатель на пример. Вкратце ваш обратный вызов вызывается с действиями, которые будут предприняты, например, вы можете отклонить все, что будет записано в базу данных.
С точки зрения эффективности, вы можете улучшить ситуацию в зависимости от того, как вызывающий абонент использует результаты. Курсоры очень дешевые. Нет необходимости снова и снова повторять одно и то же, и это может привести к незначительным ошибкам. SQLite получает следующий ряд результатов только тогда, когда вы его запрашиваете. Используя fetchall, вы настаиваете на создании списка всех результатов. Если список может быть большим или вы можете прекратить часть пути, просто верните db.cursor().execute("... query ...")
. Затем вызывающая сторона должна использовать вашу функцию для итерации:
for id,matbefore,matafter,name,date in readdb(...):
... do something ...
На вашем месте я бы просто отбросил эту функцию readdb, так как она не добавляет никакого значения, и напрямую писал запросы:
for id,foo,bar in db.cursor().execute("select id,foo,bar from .... where ...."):
... do something ...
Ваш стиль кодирования означает, что вы довольно плохо знакомы с Python. Я настоятельно рекомендую поискать итераторы и генераторы. Это гораздо более простой стиль кодирования, производящий и потребляющий результаты по мере необходимости.
Кстати, этот SQL создает таблицу с именем нулевой длины и столбцами с двойными кавычками и точками с запятой. SQLite прекрасно работает, но не делайте этого :-) Однако он полезен для тестирования.
create table "" (["], ";");
Раскрытие информации: я автор APSW