OperationalError: base de données est verrouillée
J'ai fait certaines opérations répétitives dans mon application (tester), et tout à coup j'ai une erreur bizarre:
OperationalError: database is locked
J'ai redémarré le serveur, mais l'erreur persiste. Que peut-il être tout au sujet?
Vous devez vous connecter pour publier un commentaire.
De django doc:
http://docs.djangoproject.com/en/dev/ref/databases/#database-is-locked-errorsoption
create_engine('sqlite:///{}'.format(xxx), connect_args={'timeout': 15})
La pratique de la raison pour cela est que, souvent, le python ou django coquilles ont ouvert une requête à la base de données et il n'est pas fermé correctement; le massacre de votre borne d'accès souvent libère vers le haut. J'ai eu cette erreur sur la commande en cours tests en ligne aujourd'hui.
Edit: je obtenir périodique upvotes sur cette. Si vous voulez tuer l'accès sans avoir à redémarrer le terminal, puis, à partir de la ligne de commande que vous pouvez faire:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<subfolder_with_setings.json>.settings")
Sinon, à mon humble avis la meilleure réponse icidb.connections.close_all()
pointe. Je cherchais quelque chose qui pourrait déverrouiller la base de données avant que je débourser pour un nettoyage de script danstearDown()
. Ce qu'il est corrigé. Merci.Dans mon cas, C'était parce que j'ouvrez la base de données de SQLite Browser. Quand je ferme depuis le navigateur, le problème a disparu.
Je suis en désaccord avec @Patrick réponse qui, en citant ce doc, implicitement liens OP problème (
Database is locked
) à ceci:C'est un peu "trop facile" pour incriminer SQlite pour ce problème (qui est très puissant quand il est utilisé correctement, ce n'est pas seulement un jouet pour les petites bases de données, fait amusant:
An SQLite database is limited in size to 140 terabytes
).Sauf si vous avez un de très occupé serveur avec des milliers de connexions à la même seconde, la raison de cette
Database is locked
erreur est probablement plus une mauvaise utilisation de l'API, que d'un problème inhérent à SQlite qui serait "trop léger". Voici plus d'informations sur La mise en œuvre des Limites pour SQLite.Maintenant la solution:
J'ai eu le même problème quand j'ai été en utilisant deux scripts à l'aide de la même base de données en même temps:
Solution: toujours faire
cursor.close()
dès que possible après avoir fait un (même en lecture seule) de la requête.Voici plus de détails.
Comme d'autres l'ont dit, il y a un autre processus qui utilise le fichier SQLite et n'a pas fermé la connexion. Dans le cas où vous utilisez Linux, vous pouvez voir quels sont les processus à l'aide du fichier (par exemple
db.sqlite3
) à l'aide de lafuser
commande comme suit:Si vous voulez arrêter le processus pour libérer le verrou, l'utilisation
fuser -k
qui envoie leKILL
signal à tous les processus d'accès au fichier:Noter que cette situation est dangereuse car elle peut arrêter le processus du serveur web dans un serveur de production.
Grâce à @cz-jeu pour souligner
fuser
!sudo fuser -k app.db
dans mon casJ'ai rencontré ce message d'erreur dans une situation qui n'est pas (clairement) visées par les informations d'aide liés à patrick réponse.
Lorsque j'ai utilisé
transaction.atomic()
pour envelopper un appel àFooModel.objects.get_or_create()
et appelé code simultanément à partir de deux threads différents, un seul thread réussir, tandis que l'autre serait d'obtenir la "base de données est verrouillée erreur". Modification du délai d'attente de la base de données de l'option a eu aucun effet sur le comportement.Je pense que cela est dû au fait que sqlite ne peut pas gérer simultanément plusieurs écrivains, de sorte que la demande doit sérialiser écrit sur leur propre.
J'ai résolu le problème en utilisant un
threading.RLock
objet au lieu detransaction.atomic()
quand mon Django app est en cours d'exécution avec sqlite backend. Ce n'est pas entièrement équivalentes, de sorte que vous devrez peut-être faire quelque chose d'autre dans votre application.Voici mon code qui s'exécute
FooModel.objects.get_or_create
simultanément à partir de deux threads différents, dans le cas où il est utile:Pour moi, il est résolu une fois que j'ai fermé le django shell qui a été ouvert à l'aide de
python manage.py shell
J'ai eu la même erreur! L'une des raisons était la DB connexion n'a pas été fermé.
Par conséquent, vérifiez unclosed DB connections. Aussi, vérifiez si vous avez commis la DB avant de fermer la connexion.
Cela pourrait également se produire si vous êtes connecté à votre db sqlite via dbbrowser plugin via pycharm. Déconnexion permettra de résoudre le problème
Dans mon cas, je n'avais pas sauvegardé une opération de base de données j'ai effectué au sein de l'SQLite Browser. D'économie, il a résolu le problème.
Mise à JOUR django version 2.1.7
J'ai eu cette erreur
sqlite3.OperationalError: database is locked
à l'aide depytest
avecdjango
.Solution:
Si nous sommes à l'aide de
@pytest.mark.django_db
décorateur. Ce qu'il fait est de créer unin-memory-db
pour les tests.Nommé:
file:memorydb_default?mode=memory&cache=shared
On peut obtenir avec ce nom:Pour accéder à cette base de données et également de le modifier, le faire:
Se connecter à la base de données:
Utilisation
uri=True
spécifie le fichier de disque qui est à la base de données SQLite pour être ouvert.Pour éviter l'erreur d'activation de transactions dans le décorateur:
Fonction finale:
pytest
et je ne sais pas cepytest.mark.django_db
n'. Le sqlite docs ne pas dire que les bases de données en mémoire un autre simultanéité des contraintes.essayer cette commande: