1

我有 django 1.3.1、python2.6 和 MySQL 5.5.20。 init_command在 setting.py 中设置为SET storage_engine=INNODB.

我有以下情况:

考虑模型:

class Fruit(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

现在我打开两个 Django shell 并输入:

django外壳我:

./manage.py shell
(InteractiveConsole)
>>> import fruits.models as m
>>> m.Fruit(name="apple").save()
>>> m.Fruit.objects.get(pk=1)    
<Fruit: apple>

django 外壳二:

./manage.py shell
(InteractiveConsole)
>>> import fruits.models as m
>>> m.Fruit.objects.get(pk=1)    
<Fruit: apple>

到现在为止还挺好。现在我继续输入shell I

>>> m.Fruit(name="peach").save()
>>> m.Fruit.objects.get(pk=2)
<Fruit: peach>

问:为什么在shell II 中输入以下内容找不到对象?

>>> m.Fruit.objects.get(pk=2)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "..../django/db/models/manager.py", line 132, in get
    return self.get_query_set().get(*args, **kwargs)
  File "..../django/db/models/query.py", line 349, in get
    % self.model._meta.object_name)
DoesNotExist: Fruit matching query does not exist.

我发现让 shell II “焕然一新”的唯一方法是:

>>> from django.db import transaction
>>> transaction.enter_transaction_management()
>>> transaction.rollback()

如果我想确保 orm 不会“撒谎”,我roolback()每次查询水果时都需要这样做。

4

1 回答 1

2

这是一个隔离问题。您可以放松到“隔离级别读取提交”以避免这种行为。此外,了解这种隔离级别的含义(幻象)。

要将 Read Committed Isolation Level 设置为您的 django 项目的 MySQL,您应该在 settings.py 中设置此参数:

DATABASE_OPTIONS = { 
     "init_command": 'SET storage_engine=INNODB,    \
                      SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', }
于 2012-08-27T21:06:17.257 回答