Ошибка SQLite "попытка записи базы данных только для чтения" во время вставки?

У меня есть база данных SQLite, которую я использую для веб-сайта. Проблема в том, что когда я пытаюсь INSERT INTO, я получаю PDOException

SQLSTATE[HY000]: General error: 8 attempt to write a readonly database

I SSH'd на сервер и проверял разрешения, а база данных имеет разрешения

-rw-rw-r--

Я не знаком с разрешениями * nix, но я уверен, что это означает

  • Не каталог
  • У владельца есть права на чтение/запись (что я, согласно ls -l)
  • У группы есть права на чтение/запись.
  • У всех остальных есть разрешения на чтение

Я также искал всюду, что знал, используя программу sqlite3, и не нашел ничего полезного.

Поскольку я не знал, с какими разрешениями PDO пытается открыть базу данных, я сделал

chmod o+w supplies.db

Теперь я получаю еще один PDOException:

SQLSTATE[HY000]: General error: 14 unable to open database file

Но он ТОЛЬКО возникает, когда я пытаюсь выполнить запрос INSERT после открытия базы данных.

Любые идеи о том, что происходит?

Ответ 1

Проблема, как выясняется, заключается в том, что драйвер PDO SQLite требует, чтобы если вы собираетесь выполнять операцию записи (INSERT, UPDATE, DELETE, DROP и т.д.), тогда папка, в которой находится база данных, должна иметь права на запись, а также фактический файл базы данных.

Я нашел эту информацию в комментарии в самой нижней части страницы руководства драйвера PDO SQLite.

Ответ 2

Это может произойти, когда владелец самого файла SQLite не совпадает с владельцем script. Подобные ошибки могут возникать, если не удается записать весь путь к каталогу (т.е. каждый каталог по пути).

Кому принадлежит файл SQLite? Вы?

Кто работает script как? Apache или никто?

Ответ 3

Для меня проблема заключалась SELinux, а не разрешения. Ошибка "только для чтения" исчезла после того, как я отключил принудительное выполнение,, следуя предложению Стив В. в комментарии к принятому ответу.

echo 0 >/selinux/enforce

После запуска этой команды все работало по назначению (CentOS 6.3).

Конкретная проблема, с которой я столкнулся, была при настройке Graphite. Я проверил три раза, что пользователь Apache принадлежит и может написать как мой графит .db, так и его родительский каталог. Но до тех пор, пока я не "зафиксировал" SELinux, все, что у меня было, это трассировка стека: DatabaseError: попытайтесь написать базу данных только для чтения

Ответ 4

Это может быть вызвано SELinux. Если вы не хотите полностью отключать SELinux, вам нужно установить fcontext db directory в httpd_sys_rw_content_t.

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/railsapp/db(/.*)?"
restorecon -v /var/www/railsapp/db

Ответ 5

Я получил ту же ошибку из IIS под Windows 7. Чтобы исправить эту ошибку, мне пришлось добавить полные права на управление учетной записью IUSR для файла базы данных sqlite. Вам не нужно изменять разрешения, если вы используете sqlite под webmatrix вместо IIS.

Ответ 6

Я получил эту ошибку при попытке записи в базу данных в системе Android.

Очевидно, sqlite3 нужны не только разрешения на запись в файл базы данных и содержащий каталог (как @austin-hyde уже сказал в своем ответе), но и переменная TMPDIR должна указывать на (возможно, доступный для записи) каталог.

В моей системе Android я установил TMPDIR="/data/local/tmp" и теперь мой скрипт работает так, как ожидалось :)

Редактировать:

Если вы не можете установить переменные среды, вы можете использовать один из других методов, перечисленных здесь: https://www.sqlite.org/tempfiles.html#teilitary_file_storage_locations, например PRAGMA temp_store_directory = 'directory-name';

Ответ 7

Итак, я исправил проблему, поместив файл базы данных (*.db) в подпапку.

  • Подпапка и файл базы данных внутри нее должны входить в группу www-data.
  • В группе www-data вы должны иметь право на запись в подпапку и файл базы данных.

Ответ 8

Я получил это в своем браузере, когда я перешел из http://localhost в http://my.local.ip.address, а затем снова изменился на localhost - необходимо было оставаться с IP-адресом, как только я изменил его на один раз