【问题标题】:Django error happens sometimes有时会发生 Django 错误
【发布时间】:2014-01-16 22:35:13
【问题描述】:

我现在很困惑。我在 Django 中运行一个脚本来创建一个假数据库,一遍又一遍地循环相同的代码。当我收到以下错误时,我已经创建了超过 2.5k 个对象:

ProgrammingError: autocommit cannot be used inside a transaction

我查了一下,得到了一个明显已修复的 bug-ticket,但那是针对以前的版本,我使用的是 Django 1.6。这是完整的回溯:

---------------------------------------------------------------------------
ProgrammingError                          Traceback (most recent call last)
<ipython-input-31-0597bce30f92> in <module>()
----> 1 make_listeners()

<ipython-input-29-5697f122e144> in make_listeners()
     28                         seed = random.randint(0,len(user_ids_copy)-1)
     29                         requested_user = user_ids_copy.pop(seed)
---> 30                         user.functions.listen_to(requested_user)
     31                         print i, user.pk, number_seed, original_seed
     32                         number_seed -= 1

.../models.py in listen_to(self, user_id)
    715                 except User.DoesNotExist:
    716                         return 'User DoesNotExist'
--> 717                 request = ListenerRequest.objects.get_or_create(user=requesting, user_requested=requester, is_active=True)
    718                 if not request[1]:
    719                         if request.is_accepted:

/Library/Python/2.7/site-packages/Django-1.6-py2.7.egg/django/db/models/manager.pyc in get_or_create(self, **kwargs)
    152
    153     def get_or_create(self, **kwargs):
--> 154         return self.get_queryset().get_or_create(**kwargs)
    155
    156     def create(self, **kwargs):

/Library/Python/2.7/site-packages/Django-1.6-py2.7.egg/django/db/models/query.pyc in get_or_create(self, **kwargs)
    378                 obj = self.model(**params)
    379                 with transaction.atomic(using=self.db):
--> 380                     obj.save(force_insert=True, using=self.db)
    381                 return obj, True
    382             except DatabaseError:

/Library/Python/2.7/site-packages/Django-1.6-py2.7.egg/django/db/transaction.pyc in __exit__(self, exc_type, exc_value, traceback)
    328                     connection.autocommit = True
    329                 else:
--> 330                     connection.set_autocommit(True)
    331             # Outermost block exit when autocommit was disabled.
    332             elif not connection.savepoint_ids and not connection.commit_on_exit:

/Library/Python/2.7/site-packages/Django-1.6-py2.7.egg/django/db/backends/__init__.pyc in set_autocommit(self, autocommit)
    331         self.validate_no_atomic_block()
    332         self.ensure_connection()
--> 333         self._set_autocommit(autocommit)
    334         self.autocommit = autocommit
    335

/Library/Python/2.7/site-packages/Django-1.6-py2.7.egg/django/db/backends/postgresql_psycopg2/base.pyc in _set_autocommit(self, autocommit)
    171     def _set_autocommit(self, autocommit):
    172         if self.psycopg2_version >= (2, 4, 2):
--> 173             self.connection.autocommit = autocommit
    174         else:
    175             if autocommit:

ProgrammingError: autocommit cannot be used inside a transaction

如果前 2500 个对象没有出现此问题,为什么会出现此错误?

型号:

根据要求,这是ListenerRequest 的模型,因为这似乎导致了错误:

class ListenerRequest(models.Model):
    listener_relationship_id = models.AutoField(primary_key=True)
    #user is the person asking to listen
    user = models.ForeignKey(User, related_name='requests')
    #user_requested is the person being asked to be listen to
    user_requested = models.ForeignKey(User, related_name='requested')
    date_requested = models.DateTimeField(auto_now_add=True)
    date_accepted = models.DateTimeField(null=True,blank=True)
    denied_flag = models.BooleanField(default=False)
    denied_date = models.DateTimeField(null=True,blank=True)
    unlistened_flag = models.BooleanField(default=False)
    unlistened_date = models.DateTimeField(null=True,blank=True)
    is_active = models.BooleanField(default=True)
    is_accepted = models.BooleanField(default=False)

【问题讨论】:

  • 您的数据库及其版本是什么?
  • 查看 models.py 中的代码会很有帮助。似乎get_or_create() 在您修改其他对象时尝试创建对象?
  • @Rohan 我给了你相关的模型(完整的文件大约1200行代码,所以我不会发布)
  • 看起来你是在事务中运行这个,并且在 django.db.transaction.Atomic.__exit__() 中还有另一个错误。您是否设置了 settings.ATOMIC_REQUESTS,或者您是否以任何其他方式使用事务?
  • 我有时会遇到同样的错误。你弄清楚是什么原因了吗?你使用像 django-postgrespool 这样的应用吗?

标签: python django error-handling


【解决方案1】:

如果您使用的是 django_postgrespool,则当前版本(在撰写本文时)正在吞噬错误并返回一般错误“ProgrammingError: autocommit cannot be used inside a transaction”。

您可以通过在 settings.py 中临时注释掉以下行来查看实际错误

DATABASES['default']['ENGINE'] = 'django_postgrespool'

有关更多详细信息,请参阅此当前未解决的问题:https://github.com/kennethreitz/django-postgrespool/issues/24

【讨论】:

    【解决方案2】:

    在尝试创建假数据库之前,请尝试以下操作:

    from django.db import connection
    curs = connection.cursor()
    curs.execute('SET autocommit = 1')
    

    【讨论】:

      【解决方案3】:

      thisDjango 1.3python-psycopg2 2.4.2 (oneiric version) 之间不兼容。建议的解决方法是使用以前版本的 python-psycopg2 或更新到 django 主干,因为这不会出现在下一个版本中,AFAICT 目前还没有 1.4 版本。

      试试这个:sudo pip install psycopg2==2.4.1

      【讨论】:

        猜你喜欢
        • 2015-07-25
        • 2018-05-19
        • 1970-01-01
        • 2020-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-04
        相关资源
        最近更新 更多