sqlite3.ProgrammingError: Ne peut pas fonctionner sur un fermé de la base de données. [Python] [sqlite]
Je suis l'aide d'une fonction commune pour l'exécution de tous sqlite requêtes dans une classe. Tout cela fonctionne, jusqu'à ce que je utiliser une boucle for avec plus d'un élément dans la liste.
Ici de la commune de la fonction qui s'exécute sqlite requêtes:
def executeQuery(self, query, params = ()):
results = {}
try:
cur = self.conn.cursor()
cur.execute(query, params)
self.conn.commit()
rows = cur.fetchall()
results['status'] = 'success'
result = []
if rows:
column = map(lambda x: x[0], cur.description)
for row in rows:
result.append( dict(zip(column, row)) )
results['results'] = result
except self.conn.Error, e:
if self.conn:
self.conn.rollback()
print "Error: %s" % e.args[0]
results['status'] = 'failure'
results['results'] = e.args[0]
finally:
if self.conn:
self.conn.close()
return results
Et voici la boucle qui me met à la base de données fermée erreur:
stages = self.getStageByDate(2000)
for stage in stages['results']:
print stage['name']
additives = self.getStageAdditives(stage['name'])
print additives
for additive in additives['results']:
print additive
Erreur semble provenir de la getStageAdditives()
comme il le retour des 4 éléments, tandis que getStageByDate()
retour seulement 1.
Il me semble que la connexion à la base de données n'est pas fermé avant la deuxième tentative de connexion. Pourquoi est-ce arrivé? Il ne s'est pas produit lorsqu'il est utilisé avec base de données MySQL. Quelles sont les solutions à ce problème?
OriginalL'auteur DominicM | 2014-04-13
Vous devez vous connecter pour publier un commentaire.
Vous écrivez "Il me semble que la connexion à la base de données n'est pas fermé avant la deuxième tentative de connexion" mais, en fait, il n'y a pas de "deuxième" connexion à la base de données. Vous êtes à l'aide d'une seule connexion, qui je suppose est créé dans l'initialiseur (
__init__
) pour le non-montré-dans-votre-exemple de la classe qui contient la méthodeexecute_query
.Vous (encore une fois deviner) de créer la
conn
dans ce__init__
méthode, mais vous fermez immédiatement après l'exécution d'une requête. Par conséquent, il ne sera pas disponible lorsque vous exécuter une autre requête.Au lieu de cela, vous ne devriez pas
.close()
mais plutôt.commit()
à la fin de votre requête. Ne pas le faire dansfinally
mais plutôt à la fin de latry
. De cette façon, l'opération s'être engagé (si il y arrive) ou annulée (à l'exception du bloc, en cas d'échec).Ensuite, ajoutez un distinct
.close()
méthode pour votre plus grande classe qui à son tour appelle.close()
sur la connexion, et ont le programme appelant appel que méthode lorsque c'est fini, avec toutes ses interrogations. Cet appel à proximité, permettrait d'apparaître dans unfinally
bloc à l'intérieur le plus grand programme.Cela dépend de combien de temps vous avez l'intention de garder cette classe autour et si vous le faites tout type de filetage. Les objets que vous créez de cette classe ne sera pas thread-safe, chaque thread aura besoin de sa propre connexion. Mais si vous n'êtes pas threading et sont prudents, toujours proche de l'objet lorsque vous avez terminé avec elle alors c'est trouver d'avoir une connexion pour la durée de vie de l'objet (et, en effet, c'est la façon dont je le fais).
Et oui, je n'ai rater l'instruction commit.
Je vais avoir quelques threading, mais il fera appel à des méthodes de cette classe, sera à l'origine des problèmes? Ne la création d'une nouvelle connexion à chaque fois que causer des problèmes de performance (performance n'est pas un gros souci)?
Si le
__init__
méthode de l'objet crée leconnection
, et chaque thread crée sa propre instance de l'objet, alors vous serait en sécurité.OriginalL'auteur Larry Lustig
Enlever cela de code
Il permettra de résoudre le problème, car lorsque vous souhaitez récupérer les informations de la base de données vous ne pouvez pas écrire
OriginalL'auteur Muhammad Abdullah
Pourquoi est une méthode d'affaires de la fermeture de la connexion? Sûrement, il doit fermer le curseur à la place? La fermeture de la connexion signifierait que la deuxième fois que le
executeQuery
est appelé, il ne pourrait pas parce que la connexion est allé.Dans ce cas,
executeQuery
est la “méthode des affaires”. Et non, je ne peux pas; je ne connais pas Python assez bien pour écrire un bon exemple. (J' connaître les API SQLite, mais principalement dans d'autres langues.)Vous étiez sur la bonne voie, mais non, vous ne pouvez pas fermer un curseur comme il n'y a pas de méthode close() pour un curseur. J'ai juste besoin de retirer la conn.close() au total.
OriginalL'auteur Donal Fellows