2009-07-14 5 views
11

J'utilise une base de données SQLite dans un script CGI Perl accessible par DBD::SQLite. Ceci est exécuté comme un CGI droit sur Apache.Pourquoi DBD :: SQLite ne peut-il pas être inséré dans une base de données via mon script Perl CGI?

La connexion DBI fonctionne correctement et les sélections peuvent être exécutées. Cependant, lorsque je tente de faire un insert je reçois un dé avec l'erreur suivante:

DBD::SQLite::st execute failed: unable to open database file(1) at dbdimp.c line 402 at index.cgi line 66 

J'ai essayé de changer l'autorisation de fichier de base de données 666 pour essayer de résoudre ce problème mais je reçois toujours l'erreur.

Un conseil?

+1

Pouvez-vous définir temporairement le répertoire et le fichier sur 777 et le revérifier? –

+0

Ah, ha! La modification des autorisations de répertoire sur 777 a corrigé ce problème. Savez-vous pourquoi c'est? –

+0

Vous avez probablement oublié de définir la bonne autorisation de répertoire. –

Répondre

22

Il semble que les besoins de l'annuaire écrivent l'autorisation, la raison est la suivante:

SQLite needs to be able to create a journal file in the same directory as the DB, before any modifications can take place. The journal is used to support transaction rollback.

De: seem to need write permission on db's parent directory

1

SQLite verrouille momentanément le fichier entier lorsqu'il effectue des insertions et des mises à jour (il n'y a pas de verrouillage au niveau de l'enregistrement en tant que tel). Êtes-vous sûr de libérer les verrous? La documentation SQLite recommande de démarrer une transaction, de collecter tous vos insertions et mises à jour du jour dans cette transaction, puis de valider. Cela évite de nombreux verrous de fichiers successifs et améliore les performances.

1

Depuis SQLite verrouille le fichier base de données entière, vous pouvez utiliser un mécanisme de nouvelle tentative basé délai d'attente, . Je travaillais à peu près le même problème quand j'ai demandé ce question.

Je fini par écrire quelque chose de similaire à Mark Fowler Attempt qui retente si l'exception lancée par le sous correspond à une expression régulière, dans mon cas:

qr(already in a transaction|database is locked)i 
1

Le chemin vers le répertoire où réside le fichier db doit avoir à la fois des bits exécutables et modifiables, afin d'y accéder à partir du script. De plus, si vous ne voulez pas que le fichier db soit directement accessible (même sans utiliser de fichiers spéciaux du serveur), il doit avoir des droits d'accès tels que 600 et si le répertoire contenant ne doit pas être directement consulté (encore, sans l'utilisation de fichiers de serveur spéciaux) il devrait avoir des permissions d'accès telles que 700.

J'utilise cette configuration et cela fonctionne bien localement et sur le serveur où j'héberge mon site.

Bien sûr, l'autorisation du répertoire contenant ne peut pas être 700 s'il existe un autre fichier à l'intérieur qui devrait être accessible via html, css ou javascript. Il devrait être 755 à la place.

Questions connexes