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を実行しようとしたときにのみ発生します。
何が起こっているのか?
問題は、PDO SQLiteドライバーが書き込み操作を行う場合(INSERT
、UPDATE
、DELETE
、DROP
、など)、データベースが存在するフォルダには、実際のデータベースファイルと同様に書き込み権限が必要です。
PDO SQLiteドライバーマニュアルページの一番下のコメント でこの情報を見つけました。
これは、SQLiteファイル自体の所有者がnotを実行しているユーザーと同じ場合に発生する可能性があります。ディレクトリパス全体(途中の各ディレクトリを意味する)に書き込みできない場合、同様のエラーが発生する可能性があります。
SQLiteファイルの所有者は誰ですか?君は?
スクリプトの実行者は誰ですか? ApacheまたはNobody?
私にとっての問題は、パーミッションではなく SELinuxの施行 でした。 「読み取り専用データベース」エラーは、スティーブVが 受け入れられた答えについてのコメントで提案した後、私が無効化された実施でなくなると消えました。
echo 0 >/selinux/enforce
このコマンドを実行すると、すべてが意図したとおりに機能しました(CentOS 6.3)。
私が遭遇した特定の問題は、グラファイトのセットアップ中にありました。私は、Apacheユーザーが所有し、graphite.dbとその親ディレクトリの両方に書き込みできることをトリプルチェックしました。しかし、SELinuxを「修正」するまでは、次の効果のスタックトレースしか得られませんでした。DatabaseError:読み取り専用データベースの書き込み試行
これは、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
Windows 7のIISから同じエラーが発生しました。このエラーを修正するには、sqliteデータベースファイルのIUSRアカウントにフルコントロールのアクセス許可を追加する必要がありました。 IISの代わりにwebmatrixでsqliteを使用する場合、権限を変更する必要はありません。
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';
要約すると、データベースファイル(* .db)をサブフォルダーに入れることで問題を修正しました。