Очевидно, Cursor.execute
не поддерживает команду 'commit'. Он поддерживает команду 'begin', но это избыточно, потому что sqlite3 начинает их для вас в любом случае:
>>> import sqlite3
>>> conn = sqlite3.connect(':memory:')
>>> cur = conn.cursor()
>>> cur.execute('begin')
<sqlite3.Cursor object at 0x0104B020>
>>> cur.execute('CREATE TABLE test (id INTEGER)')
<sqlite3.Cursor object at 0x0104B020>
>>> cur.execute('INSERT INTO test VALUES (1)')
<sqlite3.Cursor object at 0x0104B020>
>>> cur.execute('commit')
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
cur.execute('commit')
OperationalError: cannot commit - no transaction is active
>>>
просто используйте метод commit
для вашего Connection
объекта.
Что касается вашего второго вопроса, не обязательно вызывать begin / commit при объединении файлов: просто убедитесь, что нет абсолютно никаких ошибок на диске, изменений в БД или людей, которые смотрят на компьютер неправильно, когда он это происходит. Так что начать / зафиксировать это, вероятно, хорошая идея. Конечно, если исходные базы данных не модифицируются (я честно не смотрел), то в этом даже нет необходимости. Если есть ошибка, вы можете просто отказаться от частичного вывода и начать заново.
Это также обеспечивает ускорение, потому что каждое изменение не должно записываться на диск по мере его появления. Они могут быть сохранены в памяти и записаны навалом. Но, как уже упоминалось, sqlite3
обрабатывает это для вас.
Также стоит упомянуть, что
cmd = "attach \"%s\" as toMerge" % "b.db"
неверно в том смысле, что это испорчено. Если вы хотите правильно поступить неправильно, это
cmd = 'attach "{0}" as toMerge'.format("b.db") #why not just one string though?
Это совместимо с новыми версиями python, что упрощает перенос кода.
если вы хотите сделать правильную вещь, это
cmd = "attach ? as toMerge"
cursor.execute(cmd, ('b.db', ))
Это позволяет избежать инъекций sql и, по-видимому, немного быстрее, так что это беспроигрышный вариант.
Вы можете изменить свой метод runCommand
следующим образом:
def runCommand(self, sql, params=(), commit=True):
self.cursor.execute(sql, params)
if commit:
self.connector.commit()
теперь вы не можете коммитить после каждой команды, передавая commit=False
, когда вам не нужен коммит. Это сохраняет понятие транзакции.