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

95

У меня есть база данных 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 после открытия базы данных.

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

  • 0
    в основном httpd (apache> php> PDO) - это не вы, поэтому он не является владельцем файла, поэтому у него нет прав на запись ... интересно ...
  • 0
    sudo chgrp www-data test.db меня sudo chgrp www-data test.db с добавлением разрешений работал
Теги:
permissions

7 ответов

251
Лучший ответ

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

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

  • 8
    Кроме того, SELinux (если установлен) не должен быть принудительным. У меня ушло полтора дня, чтобы понять это.
  • 0
    Также применимо к ruby-sqlite, спасибо большое!
Показать ещё 5 комментариев
12

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

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

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

  • 1
    У меня есть файл SQLite, но я не знаю, с кем работает скрипт. Как я могу узнать? (Имейте в виду, что это на общем хосте, и у меня ограниченные разрешения)
  • 1
    Ах, это делает вещи веселее. Если вы пользуетесь виртуальным хостингом, очень вероятно, что скрипт запускается как «nobody» или «apache». Пусть ваш скрипт создаст файл ( file_put_contents('./foo.txt', 'Hello, world'); ), который покажет вам, с кем он работает. Скорее всего, вам понадобится скрипт для создания базы данных SQLite. Это может быть занимательным упражнением, если у вас уже есть данные в вашем текущем файле ...
Показать ещё 5 комментариев
4

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

echo 0 >/selinux/enforce

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

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

  • 6
    SELinux - это мера безопасности, поэтому ее не следует отключать без веской причины. Было бы лучше выяснить, почему SELinux блокирует в первую очередь, и правильно его настроить, а не отключать.
  • 1
    У тебя есть лучшее решение, @ jens-wegar?
2

Это может быть вызвано 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
1

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

0

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

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

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

  • 0
    Я использую pydroid3. Как я могу установить в нем tmpdir?
  • 0
    @AbdullahMallik К сожалению, я не знаю pydroid3, может быть, искать какой-то параметр под названием «переменная (и) среды» или «среда» или «env»
Показать ещё 2 комментария
-1

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню