django TransactionManagementError lors de l'utilisation de signaux
J'ai un champ avec de django reinhardt, les utilisateurs et les UserInfo. Je souhaite m'abonner à la post_save fonction de rappel sur le modèle de l'utilisateur, de sorte que j'ai la possibilité d'enregistrer les UserInfo.
@receiver(post_save, sender=User)
def saveUserAndInfo(sender, instance, **kwargs):
user = instance
try:
user.user_info.save()
except:
info = UserInfo()
info.user = user
info.save()
Cependant, je suis un TransactionManagementError
quand j'ai essayer de le faire. Je suis en supposant que parce que le modèle de l'utilisateur n'a pas terminé l'enregistrement et je suis en train de lire l'id de l'enregistrer sur le user_info. Quelqu'un sait comment le faire correctement?
Un deuxième problème. Je voulais joindre une UserInfo exemple à un utilisateur dès que l'utilisateur a été créé. Donc sur post_init j'ai essayé de créer un UserInfo instance et de l'affecter à l'utilisateur instance, mais cela ne fonctionne pas car l'utilisateur n'a pas été attribué un pk encore. Je suppose que je dois juste attendre jusqu'à ce que post_save (ou plus tard) pour créer cette instance. Est-ce la seule façon de le faire?
Traceback:
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
430. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
99. response = view_func(request, *args, **kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
52. response = view_func(request, *args, **kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
198. return view(request, *args, **kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
29. return bound_func(*args, **kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
99. response = view_func(request, *args, **kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
25. return func(self, *args2, **kwargs2)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/transaction.py" in inner
339. return func(*args, **kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view
1129. self.save_model(request, new_object, form, False)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/contrib/admin/options.py" in save_model
858. obj.save()
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/base.py" in save
545. force_update=force_update, update_fields=update_fields)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/base.py" in save_base
582. update_fields=update_fields, raw=raw, using=using)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/dispatch/dispatcher.py" in send
185. response = receiver(signal=self, sender=sender, **named)
File "/Users/croberts/lunchbox/userinfo/models.py" in saveUserAndInfo
83. info.save()
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/base.py" in save
545. force_update=force_update, update_fields=update_fields)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/base.py" in save_base
573. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
654. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
687. using=using, raw=raw)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/manager.py" in _insert
232. return insert_query(self.model, objs, fields, **kwargs)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/query.py" in insert_query
1511. return query.get_compiler(using=using).execute_sql(return_id)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
898. cursor.execute(sql, params)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/backends/util.py" in execute
69. return super(CursorDebugWrapper, self).execute(sql, params)
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/backends/util.py" in execute
47. self.db.validate_no_broken_transaction()
File "/Users/croberts/.virtualenvs/lunchbox/lib/python2.7/site-packages/django/db/backends/__init__.py" in validate_no_broken_transaction
365. "An error occurred in the current transaction. You can't "
Exception Type: TransactionManagementError at /gov/auth/user/add/
Exception Value: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
Juste mis à jour avec le traceback.
Essayez de mettre
sp = transaction.savepoint()
avant try: except:
, transaction.savepoint_rollback(sp)
juste après except:
et avantinfo = UserInfo()
et transaction.savepoint_commit(sp)
à votre finally:
près de try: except:
.J'obtiens la même erreur.
OriginalL'auteur Chase Roberts | 2013-11-21
Vous devez vous connecter pour publier un commentaire.
L'erreur est causée par le
user.user_info.save()
de la ligne de lancer une exception, et la transaction a été signalée comme étant cassé (PostgreSQL applique la restauration de l'intégralité de la transaction, ou à un point de sauvegarde stockées avant de faire plus de requêtes à l'intérieur de la transaction).Vous pouvez annuler la transaction lorsqu'une erreur se produit:
C'est largement décrit dans la la documentation.
Aussi, notez que la capture de tous les types d'exception n'est généralement pas la meilleure idée que vous pourriez le silence exceptions que vous n'attendiez pas.
découvrez cette réponse. Il résout le problème.
Save() transaction qui n'est pas atomique, déjà? Avec 10k requêtes par minute, ce serait un grand changement pour mon modèle
il dépend.
save
lui-même n'est pas, bien que les opinions peuvent être atomique. Le point ici est que, depuis l'OP obtenu le message d'erreur, l'enregistrement a l'intérieur d'une transaction. Maintenant, à l'intérieur d'une transactiontransaction.atomic ()
crée un point de sauvegarde, qui obtient automatiquement rolledback sur l'exception. C'est le cas ici.OriginalL'auteur