it-swarm.com.de

SQLite: Nur-Lese-Datenbank

Ich habe eine SQLite-Datenbank, die ich für eine Website verwende. Das Problem ist, dass ich, wenn ich INSERT INTOe versuche, eine PDOException erhalte.

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

Ich habe SSH in den Server gestellt und die Berechtigungen geprüft, und die Datenbank verfügt über die Berechtigungen

-rw-rw-r--

Ich bin mit * nix-Berechtigungen nicht so vertraut, aber ich bin mir ziemlich sicher, dass dies bedeutet

  • Kein Verzeichnis
  • Besitzer hat Lese-/Schreibrechte (das bin ich, laut ls -l)
  • Gruppe hat Lese-/Schreibberechtigungen
  • Alle anderen haben nur Leseberechtigungen

Ich schaute auch überall hin, wo ich mit dem Programm sqlite3 kannte, und fand nichts relevantes.

Da ich nicht wusste, mit welchen Berechtigungen PDO versucht, die Datenbank zu öffnen, tat ich es

chmod o+w supplies.db

Nun bekomme ich noch eine PDOException:

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

Es tritt jedoch NUR auf, wenn ich versuche, eine INSERT-Abfrage auszuführen, nachdem die Datenbank geöffnet ist.

Irgendwelche Ideen, was los ist?

102
Austin Hyde

Das Problem, wie sich herausstellt, besteht darin, dass der PDO-SQLite-Treiber vorsieht, dass, wenn Sie einen Schreibvorgang ausführen (INSERT, UPDATE, DELETE, DROP usw.), der Ordner, in dem sich die Datenbank befindet, über Schreibberechtigungen verfügen muss sowie die eigentliche Datenbankdatei.

Ich habe diese Informationen in einem Kommentar am Ende der PDO SQLite-Treiber-Handbuchseite gefunden.

273
Austin Hyde

Dies kann passieren, wenn der Besitzer der SQLite-Datei selbst nicht derselbe ist wie der Benutzer, der das Skript ausführt. Ähnliche Fehler können auftreten, wenn nicht der gesamte Verzeichnispfad (dh jedes Verzeichnis auf dem Weg) geschrieben werden kann. 

Wem gehört die SQLite-Datei? Du?

Unter wem läuft das Skript? Apache oder Niemand?

12
Charles

Für mich war das Problem SELinux-Durchsetzung und nicht Berechtigungen. Der Fehler "Nur Lesen Datenbank" verschwand, als ich {Deaktivierung der Durchsetzung, dem Vorschlag von Steve V. in einem Kommentar zu der akzeptierten Antwort folgte.

echo 0 >/selinux/enforce

Nachdem dieser Befehl ausgeführt wurde, funktionierte alles wie beabsichtigt (CentOS 6.3).

Das spezifische Problem, auf das ich gestoßen war, war beim Einrichten von Graphite. Ich hatte eine dreifache Überprüfung, die der Apache-Benutzer besaß, in meine graphite.db und sein übergeordnetes Verzeichnis schreiben können. Aber bis ich SELinux "reparierte", war alles, was ich bekam, ein Stack-Trace mit der Wirkung von: DatabaseError: Versuch, eine Readonly-Datenbank zu schreiben

5
Noah Sussman

Dies kann durch SELinux verursacht werden. Wenn Sie SELinux nicht vollständig deaktivieren möchten, müssen Sie das Datenbankverzeichnis fcontext auf httpd_sys_rw_content_t setzen.

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

Ich habe den gleichen Fehler von IIS unter Windows 7 erhalten. Um diesen Fehler zu beheben, musste ich dem IUSR-Konto volle Berechtigung für die SQLite-Datenbankdatei hinzufügen. Sie müssen keine Berechtigungen ändern, wenn Sie sqlite anstelle von IIS unter webmatrix verwenden.

1
l0pan

Zusammenfassend habe ich das Problem behoben, indem ich die Datenbankdatei (* .db) in einen Unterordner verschoben habe.

  • Der Unterordner und die darin enthaltene Datenbankdatei müssen Mitglied der Gruppe www-data sein.
  • In der Gruppe www-data müssen Sie das Recht haben, in den Unterordner und in die Datenbankdatei zu schreiben.
0
Erkan Hürnalı

Ich habe diesen Fehler erhalten, als ich versuchte, in eine Datenbank auf einem Android-System zu schreiben.

Anscheinend benötigt sqlite3 nicht nur Schreibberechtigungen für die Datenbankdatei und das enthaltende Verzeichnis (wie @ austin-hyde bereits in seiner Antwort gesagt hat), sondern auch die Umgebungsvariable TMPDIR muss auf ein (möglicherweise schreibbares) Verzeichnis verweisen.

Auf meinem Android-System habe ich TMPDIR="/data/local/tmp" eingestellt und jetzt läuft mein Skript wie erwartet :)

0
Thilo