Возможно ли открыть заблокированную базу данных sqlite в режиме только для чтения?

#python #database #sqlite

#python #База данных #sqlite

Вопрос:

Я хотел бы открыть данные сайта chromium (в ~/.config/chromium/Default) с помощью python-sqlite3, но он блокируется всякий раз, когда запущен chromium, что понятно, поскольку могут быть выполнены транзакции. Есть ли способ открыть его в режиме только для чтения, гарантируя, что я не смогу повредить целостность базы данных, пока chromium ее использует?

Ответ №1:

Я считаю, что это зависит от блокировки, установленной транзакцией.

http://www.sqlite.org/lockingv3.html#shared_lock
http://www.sqlite.org/lang_transaction.html

Эксклюзивные транзакции SQLite блокируют как чтение, так и запись, в то время как немедленные и отложенные транзакции по-прежнему будут разрешать считывателям.

Так что это действительно зависит от транзакций, используемых Chromium.

Ответ №2:

Chromium удерживает блокировку базы данных в течение длительных периодов времени? Фу! Это действительно не очень хорошая идея. Тем не менее, это не ваша вина…

Вы можете попробовать просто скопировать файл базы данных (например, с помощью системной утилиты cp ) и использовать этот снимок для чтения; SQLite сохраняет все свое зафиксированное состояние в одном файле для каждой базы данных. Да, есть вероятность увидеть частичную транзакцию, но у вас определенно не будет проблем с блокировкой в Unix, поскольку SQLite определенно не использует обязательные блокировки. (Это может не сработать в Windows из-за другой схемы блокировки.)

Комментарии:

1. Это не обязательно ошибка chromium. Копаясь, я нашел это полезное сообщение, в котором указывалось, что библиотека pysqlite не предоставляет интерфейс для всех функций sqlite, поскольку она совместима с DB-API. Так что, возможно, когда я открываю базу данных с помощью pysqlite, я делаю это, не говоря уже о режиме чтения-записи. Он указал на APSW, чтобы использовать флаг SQLITE_OPEN_READONLY при запуске соединения. Я проверю это сейчас.

2. Это обходной путь, который я использовал, потому что я заблудился примерно на 15 вкладках браузера, пытаясь найти «правильное» решение для одновременного доступа к Firefox places.sqlite . То же самое с Firefox, то же сообщение об ошибке. Просто измените свою программу для работы с копией и наслаждайтесь большей частью своей жизни, не беспокоясь о PRAGMA main.journal_mode=WAL s и SQLITE_OPEN_READONLY s и не изучая документацию C API, только чтобы узнать, что вы не можете сделать то или это с sqlite3 помощью библиотеки Python.

Ответ №3:

Кажется, мы можем обойти блокировку, открыв базу данных в immutable режиме, например:

 sqlite3 'file:places.sqlite?immutable=1'
 

Как объяснено здесь https://www.sqlite.org/c3ref/open.html

Это может привести к ошибкам при запросе, если изменяется базовый файл базы данных, или, очевидно, не отображаются обновления, внесенные в файл, но я обнаружил, что повторное открытие соединения при каждом новом запросе помогает в этом.

Чтобы добиться того же с большинством драйверов SQLite, потому что мы не можем установить напрямую SQLITE_IOCAP_IMMUTABLE , лучший способ — открыть соединение с флагом SQLITE_OPEN_READONLY | SQLITE_OPEN_URI , чтобы разрешить передачу file:...?immutable=1 URI как filename .

Комментарии:

1. Приятно! echo "SELECT ..." | sqlite3 'file:///home/my_user/.mozilla/firefox/12wh3gmq.work/cookies.sqlite?immutable=1' сработало для меня! Другие способы sqllite3 -readonly ... or sqlite3 ...?mode=ro не помогали. Также sqlite3 'file://~/.mozilla/firefox/12wh3gmq.work/cookies.sqlite?immutable=1' не работает.