J'ai effectué des opérations répétitives dans mon application (en le testant) et, tout à coup, une erreur étrange se produit:
OperationalError: database is locked
J'ai redémarré le serveur, mais l'erreur persiste. De quoi peut-il s'agir?
De Django doc:
SQLite se veut léger base de données, et donc ne peut pas supporter un niveau élevé de concurrence . OperationalError: la base de données est verrouillée les erreurs indiquent que votre application connaît plus de simultanéité que sqlite peut gérer par défaut configuration. Cette erreur signifie que un thread ou processus a une exclusivité verrouiller la connexion à la base de données et un autre thread a expiré pour attendre la serrure la soit libérée.
Le wrapper SQLite de Python a une valeur par défaut valeur de délai d'attente qui détermine combien de temps le deuxième thread est autorisé à attendre sur la serrure avant la fin du délai et déclenche OperationalError: database est une erreur verrouillée.
Si vous obtenez cette erreur, vous pouvez le résoudre par:
Basculement vers un autre backend de base de données . À un moment donné, SQLite devient aussi "lite" pour des applications réelles, et ces sortes d’erreurs de concurrence indique que vous avez atteint ce point.
Réécrire votre code pour réduire concurrence et assurer cette base de données les transactions sont de courte durée.
Augmentez la valeur de délai d'attente par défaut de définition de l'option de base de données de délai d'attente optionoption
http://docs.djangoproject.com/en/dev/ref/databases/#database-is-locked-errorsoption
La raison pratique en est souvent que les shells python ou Django ont ouvert une requête à la base de données et que celle-ci n’a pas été fermée correctement; tuer votre accès au terminal le libère souvent. J'ai eu cette erreur en exécutant des tests en ligne de commande aujourd'hui.
Edit: Je reçois des votes périodiques à ce sujet. Si vous souhaitez supprimer l'accès sans redémarrer le terminal, vous pouvez effectuer une commande en ligne de commande:
from Django import db
db.connections.close_all()
Dans mon cas, c’est parce que j’ouvre la base de données à partir du navigateur SQLite. Lorsque je le ferme depuis le navigateur, le problème a disparu.
Je ne suis pas d'accord avec la réponse de @ Patrick qui, en citant ce document, lie implicitement le problème de OP (Database is locked
) à ceci:
Basculement vers un autre backend de base de données. À un moment donné, SQLite devient trop "léger" pour les applications du monde réel, et ces types d'erreur de simultanéité indiquent que vous avez atteint ce point.
C’est un peu "trop facile" d’incriminer SQlite pour ce problème. Sauf si vous avez un serveur très occupé avec des milliers de connexions à la même seconde, la cause de cette erreur Database is locked
est probablement davantage une mauvaise utilisation de l'API qu'un problème inhérent à SQlite qui serait "trop léger". Voici plus d'informations sur Limites d'implémentation pour SQLite .
Maintenant la solution:
J'ai eu le même problème lorsque j'utilisais deux scripts utilisant la même base de données en même temps:
Solution: toujours faire cursor.close()
le plus tôt possible après avoir effectué une requête (même en lecture seule).
Pour moi, le problème est résolu lorsque j'ai fermé le shell Django ouvert à l'aide de python manage.py Shell
.
Dans mon cas, je n'avais pas enregistré d'opération de base de données effectuée dans le navigateur SQLite. L'enregistrer a résolu le problème.
Cela pourrait aussi arriver si vous êtes connecté à votre base de données sqlite via le plugin dbbrowser via pycharm. La déconnexion va résoudre le problème