Dlaczego pojawia się błąd sqlite „nie można otworzyć pliku bazy danych”?

65

Korzystając z mojej aplikacji Django, mogę dobrze czytać z bazy danych. Gdy aplikacja nie miała uprawnień dostępu do pliku, dał mi ten błąd:

próba napisania bazy danych tylko do odczytu

Co miało sens. Zedytowałem więc uprawnienia do pliku, aby proces Apache miał uprawnienia do zapisu. Jednak zamiast móc pisać, pojawia się ten tajemniczy błąd:

nie można otworzyć pliku bazy danych

Jeśli jest to przydatne, oto cały wynik:

Request Method: POST
Request URL:    http://home-sv-1/hellodjango1/polls/1/vote/
Exception Type: OperationalError
Exception Value:    
unable to open database file
Exception Location: /usr/lib/pymodules/python2.5/django/db/backends/sqlite3/base.py in execute, line 193
Python Executable:  /usr/bin/python
Python Version: 2.5.2
Python Path:    ['/var/www', '/usr/lib/python2.5', '/usr/lib/python2.5/plat-linux2', '/usr/lib/python2.5/lib-tk', '/usr/lib/python2.5/lib-dynload', '/usr/local/lib/python2.5/site-packages', '/usr/lib/python2.5/site-packages', '/usr/lib/pymodules/python2.5', '/usr/lib/pymodules/python2.5/gtk-2.0']
Server time:    Sun, 23 Aug 2009 07:06:08 -0500

Daj mi znać, jeśli konieczne jest śledzenie stosu.

Nick Bolton
źródło
Wydaje się, że masz ten problem podczas wdrażania.
Mohammed Shareef C

Odpowiedzi:

79

Aha, właśnie natknąłem się na artykuł wyjaśniający to. Również Django ma informacje na swojej stronie NewbieMistakes .

Rozwiązaniem jest upewnienie się, że katalog zawierający plik bazy danych ma również dostęp do zapisu do procesu.

W moim przypadku uruchomienie tego polecenia rozwiązało problem:

sudo chown www-data .
Nick Bolton
źródło
3
Zakłada się, że korzystasz z Debiana / Ubuntu, jeśli używasz CentOS, będziesz chciał użyć „Apache” zamiast „www-data”
Luke Chadwick
3
@nbolton Uwaga: chown www-data. .tak naprawdę powinno być chown www-data .inaczej, istnieje jakiś czarodziej polecenia chown, o którym nie wiem ... proszę oświeć mnie.
Jeff Sheffield,
3
Uważam, że dodatkową kropką jest ustawienie grupy na domyślną grupę właściciela. W przeciwnym razie nie zmienia grupy. To tylko z pamięci, gorąco polecam, żebyś sam to wypróbował.
Nick Bolton
Podsumowano tutaj w przypadku przyszłego zepsucia łącza lub tl; dr: SQLite3 chce dostępu do zapisu do katalogu pliku DB, aby mógł tam utworzyć plik dziennika po otwarciu transakcji.
user1454265,
Idealne dla użytkowników systemu Linux. Bupkiss dla Windows.
Jay Blanchard,
7

Moje rozwiązanie tego było bardziej podobne. Tak naprawdę nie chciałem zmieniać właściciela tego reżimu. (głównie dlatego, że używam pi do robienia rzeczy takich jak git)

/var/www/mysite $ ls -la sql*
-rw-rw-r-- 1 pi       pi       25600 Jan  2 22:57 sqlite.db

(lub cokolwiek, którego używasz db)

gdzie pi to użytkownik, w którym utworzyłem wszystkie pliki. (tak, to malinowe pi)

Zamiast zmieniać uprawnienia do danych www, stwierdziłam, że muszę jedynie zmienić uprawnienia w następujący sposób:

sudo chmod 775 /var/www/mysite
sudo chmod 664 /var/www/mysite/sqlite.db
sudo usermod -a -G pi www-data

Daje to grupie dostęp do zapisu niezbędnych plików i dodaje użytkownika danych www do grupy pi.

Uwaga: jeśli masz logowanie, musisz to zrobić również dla pliku dziennika django, w przeciwnym razie apache nie spodoba się zbytnio.

SpiRail
źródło
1
Myślę, że mogłeś właśnie dodać użytkownika pi do grupy danych www. Mogłeś też zostawić pliki bez zmian i użyć polecenia setfacl, aby dodać listę kontroli dostępu dla pi do plików i / lub katalogów.
slm
setfacl brzmi jak potencjalnie dobra opcja. Dobrze byłoby umieścić to jako odpowiedź instruktażową. Jednym z problemów, z którym się spotykam, jest to, że muszę często testować plik .db. Kiedy zostanie odtworzony, musi zostać ponownie zmieniony.
SpiRail
Zobacz moją odpowiedź na to pytanie, serverfault.com/a/462970/2518 . Czy jest coś, co powinienem dodać do tego, co by pomogło?
slm
7

Z Django mówi: „Nie można otworzyć pliku bazy danych” przy użyciu SQLite3 sekcję z pomyłek Newbie Django wiki stronie :

  1. upewnij się, że Apache może również zapisywać w katalogu nadrzędnym bazy danych
  2. upewnij się, że żaden folder pełnej ścieżki do pliku bazy danych nie zaczyna się od cyfry
  3. upewnij się, że pełna ścieżka do dbkatalogu istnieje
  4. upewnij się, że w twoim /tmpkatalogu można zapisać świat
  5. upewnij się, że ścieżka do bazy danych określona w settings.pyto pełna ścieżka
  6. upewnij się, że na ścieżce nie ma żadnych znaków specjalnych
  7. w systemie Windows upewnij się, że ścieżka katalogu db jest zapisana z podwójnymi ukośnikami
ssc
źródło
Skopiuj / wklej odpowiednie części linku tutaj.
Christophe De Troyer
I to jest aprobata! :)
Christophe De Troyer
5

Dodanie użytkownika operacyjnego do grupy danych www działa dobrze w moim środowisku testowym. Dodatkowo umieściłem plik sqlite3.db w osobnym podfolderze , aby był bardziej bezpieczny.

Plik bazy danych jest własnością www-data

sudo chown www-data mysite/db_sqlite3/
sudo chown www-data mysite/db_sqlite3/my.db

Mój użytkownik operacyjny otrzymuje członka grupy danych www:

sudo usermod -a -G www-data hape

Zezwól na dostęp do pliku bazy danych do zapisu członkom grupy www-data:

sudo chmod u+w+x,g+w+x mysite/db_sqlite3/
sudo chmod u+w+x,g+w+x mysite/db_sqlite3/my.db

W rezultacie do bazy danych można uzyskać dostęp do odczytu i zapisu przez apache2-daemon (dane www użytkownika), bez udzielania zgody na folder główny projektu, a - z drugiej strony - aplikację można uruchomić w trybie deweloperskim przez system operacyjny Hape użytkownika, np

./manage.py runserver

również.

Hartmut P.
źródło
1

Zapożyczono z SO: https://stackoverflow.com/questions/4283132/apache-instance-user-permission-issue

Zakładając, że pliki są własnością użytkownika apache, aby rozpocząć:

% chown -R apache.apache /var/www/mysite

ustawiony ACLsdla użytkownika / grupy pi:

% setfacl -d -m u:pi:rwx /var/www/mysite
% setfacl -d -m g:pi:rwx /var/www/mysite

% getfacl /var/www/mysite
# file: /var/www/mysite
# owner: apache
# group: apache
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:pi:rwx
default:group::r-x
default:group:pi:rwx
default:mask::rwx
default:other::r-x

Można powiedzieć Jest takie ACLz ls -l, tylna „+” na bity uprawnień:

# ls -la /var/www
drwxr-xr-x   3 apache   apache   80 26. Nov 12:43 .
drwxrwxrwt  15 root     root 360 26. Nov 12:40 ..
drwxrwxr-x+  2 apache   apache   40 26. Nov 12:43 mysite
slm
źródło
Ustawienie właściciela / grupy na proces apache dla całego projektu django to zły pomysł, nie trzeba przyznawać niepotrzebnych uprawnień.
benjaoming
1

Rozwiązaniem jest upewnienie się, że katalog zawierający plik bazy danych ma również dostęp do zapisu do procesu.

W przypadku Windows 7, 8.1, 10, Server 2012 itd. Postępuj zgodnie ze wskazówkami instalacji Bonobo :

Pozwól użytkownikowi IIS modyfikować folder C: \ inetpub \ wwwroot \ Bonobo.Git.Server \ App_Data.

Aby to zrobić:

  1. wybierz Właściwości folderu App_Data,
  2. przejdź do zakładki Bezpieczeństwo,
  3. kliknij edytuj,
  4. wybierz użytkownika IIS (w moim przypadku IIS_IUSRS) i dodaj uprawnienia do modyfikacji i zapisu,
  5. potwierdź te ustawienia przyciskiem Zastosuj.
DEXTER360
źródło
0

Serwer programistyczny musi być uruchomiony jako ten sam użytkownik, który ma uprawnienia do zapisu w folderze bazy danych, więc jeśli pierwotnie utworzyłeś bazę danych jako root, będziesz musiał być rootem podczas uruchamiania:

python manage.py runserver
Kilizo
źródło
Chociaż technicznie poprawne, uruchamianie serwera rootjest okropnym pomysłem - Lepiej byłoby, gdyby chownbaza danych była dla zwykłego nieuprzywilejowanego użytkownika, który normalnie uruchamia serwer ...
voretaq7
0

utwórz podkatalog w katalogu roboczym

mkdir db-folder 

utwórz bazę danych sqlite w podkatalogu

sqlite3 db-folder/db.db

zmień właściciela podkatalogu na www-data w debain lub apache w centOS

chown -R www-data db-folder

i weź zimne piwo, bo gotowe.

P / S: aby sprawdzić, czy procedura zakończyła się powodzeniem

ls -l data-folder

powinieneś zobaczyć takie

-rw-r--r-- 2 www-data root 4096 Jun 18 01:38 data-folder
burdich
źródło
Jeśli zamierzasz opublikować odpowiedź, podaj odpowiedź, która zasadniczo różni się od innych odpowiedzi na to samo pytanie.
masegaloeh
-1

po prostu napisz sudo sqlite3 databaseFilename.sqli to działa

Alireza Valipour
źródło
To może działać w przypadku interaktywnej sesji użytkownika, ale nie jest rozwiązaniem nie do aplikacji internetowej ...
HBruijn