web-dev-qa-db-ja.com

挿入中のSQLiteエラー「読み取り専用データベースへの書き込み試行」

Webサイトに使用しているSQLiteデータベースがあります。問題は、INSERT INTOを実行しようとすると、PDOExceptionを取得することです

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

サーバーにSSHで接続してアクセス許可を確認しましたが、データベースにアクセス許可があります

-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クエリafterを実行しようとしたときにのみ発生します。

何が起こっているのか?

112
Austin Hyde

問題は、PDO SQLiteドライバーが書き込み操作を行う場合(INSERTUPDATEDELETEDROP、など)、データベースが存在するフォルダには、実際のデータベースファイルと同様に書き込み権限が必要です。

PDO SQLiteドライバーマニュアルページの一番下のコメント でこの情報を見つけました。

286
Austin Hyde

これは、SQLiteファイル自体の所有者がnotを実行しているユーザーと同じ場合に発生する可能性があります。ディレクトリパス全体(途中の各ディレクトリを意味する)に書き込みできない場合、同様のエラーが発生する可能性があります。

SQLiteファイルの所有者は誰ですか?君は?

スクリプトの実行者は誰ですか? ApacheまたはNobody?

13
Charles

私にとっての問題は、パーミッションではなく SELinuxの施行 でした。 「読み取り専用データベース」エラーは、スティーブVが 受け入れられた答えについてのコメントで提案した後、私が無効化された実施でなくなると消えました。

echo 0 >/selinux/enforce

このコマンドを実行すると、すべてが意図したとおりに機能しました(CentOS 6.3)。

私が遭遇した特定の問題は、グラファイトのセットアップ中にありました。私は、Apacheユーザーが所有し、graphite.dbとその親ディレクトリの両方に書き込みできることをトリプルチェックしました。しかし、SELinuxを「修正」するまでは、次の効果のスタックトレースしか得られませんでした。DatabaseError:読み取り専用データベースの書き込み試行

5
Noah Sussman

これは、SELinuxが原因である可能性があります。 SELinuxを完全に無効にしたくない場合は、dbディレクトリfcontextをhttpd_sys_rw_content_tに設定する必要があります。

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

Windows 7のIISから同じエラーが発生しました。このエラーを修正するには、sqliteデータベースファイルのIUSRアカウントにフルコントロールのアクセス許可を追加する必要がありました。 IISの代わりにwebmatrixでsqliteを使用する場合、権限を変更する必要はありません。

1
l0pan

Androidシステム上のデータベースに書き込もうとすると、このエラーが発生しました。

どうやらsqlite3にはデータベースファイルとそれを含むディレクトリへの書き込み権限(@ austin-hydeが回答ですでに述べたように)だけでなく、環境変数TMPDIRも(おそらく書き込み可能な)ディレクトリを指している必要があります。

AndroidシステムでTMPDIR="/data/local/tmp"に設定すると、スクリプトは期待どおりに実行されます:)

編集:

環境変数を設定できない場合は、ここにリストされている他の方法のいずれかを使用できます。 https://www.sqlite.org/tempfiles.html#temporary_file_storage_locations like PRAGMA temp_store_directory = 'directory-name';

1
Thilo

要約すると、データベースファイル(* .db)をサブフォルダーに入れることで問題を修正しました。

  • サブフォルダーとその中のデータベースファイルは、www-dataグループのメンバーである必要があります。
  • Www-dataグループでは、サブフォルダーとデータベースファイルに書き込む権利が必要です。
0
Erkan Hürnalı