Подтвердить что ты не робот

Данные дампа от неправильного SQLite в Python

У меня есть некорректная база данных. Когда я пытаюсь получить записи из любой из двух таблиц, это генерирует исключение:

DatabaseError: образ диска базы данных неверен

Я знаю, что с помощью командной строки я могу это сделать:

sqlite3 ".dump" base.db | sqlite3 new.db

Можно ли сделать что-то подобное из Python?

4b9b3361

Ответ 1

Насколько я знаю, вы не можете этого сделать (увы, я могу ошибаться), потому что модуль sqlite3 для python очень ограничен.

Только обходное решение, о котором я могу думать, включает вызов командной оболочки os (например, terminal, cmd,...) (подробнее) через pythons команда колл-:

Объедините его с информацией из здесь, чтобы сделать что-то вроде этого:

Это делается на машине Windows XP: К сожалению, я не могу проверить это на unix-машине прямо сейчас - надеюсь, что это вам поможет:

    from subprocess import check_call

    def sqliterepair():
        check_call(["sqlite3", "C:/sqlite-tools/base.db", ".mode insert", ".output C:/sqlite-tools/dump_all.sql", ".dump", ".exit"])
        check_call(["sqlite3", "C:/sqlite-tools/new.db", ".read C:/sqlite-tools/dump_all.sql", ".exit"])
        return

Первый аргумент вызывает sqlite3.exe. Поскольку это в моей переменной пути к системе, мне не нужно указывать путь или суффикс ".exe". Другие аргументы приводятся в оболочку sqlite3.

Обратите внимание, что аргумент ".exit" требуется, чтобы оболочка sqlite завершила работу. В противном случае check_call() никогда не завершится, потому что внешняя оболочка CMD или терминал будут приостановлены.

Конечно, файл дампа впоследствии должен быть удален...

EDIT: Много более короткое решение (кредит идет OP (см. комментарий))

os.system("sqlite3 C:/sqlite-tools/base.db .dump | sqlite3 C:/sqlite-tools/target.db")

Просто протестировал это: он работает. Видимо, я был не прав в комментариях.

Ответ 2

Если я правильно понял, вы хотите дублировать базу данных sqlite3 в python. Вот как я это сделаю:

# oldDB = path to the corrupted db, 
# newDB = path to the new db
def duplicateDB(oldDB, newDB):

    con = sqlite3.connect(oldDB)
    script = ''.join(con.iterdump())
    con.close()

    con = sqlite3.connect(newDB)
    con.executescript(script)
    con.close()

    print "duplicated %s into %s" % (oldDB,newDB)

В вашем примере вызовите duplicateDB('base.db', 'new.db'). Функция iterdump эквивалентна dump.

Обратите внимание, что если вы используете Python 3, вам нужно будет изменить оператор print.