升级django 2.1=>;后,用户对象.save()不保存;2.2
我遇到了一个非常奇怪的错误,我可以从django shell创建并保存一个升级django 2.1=>;后,用户对象.save()不保存;2.2,django,django-models,Django,Django Models,我遇到了一个非常奇怪的错误,我可以从django shell创建并保存一个用户,但是当我退出并重新打开shell时,用户消失了 这是在一个类似prod的环境中,有一个适当的后台数据库。如果我降级Django 2.2.8->2.1.7,问题就会消失 >>> u = User(id=123131323122, first_name='hi', last_name='sup', email='test@mysupertest.com') >>> u.set_pass
用户
,但是当我退出并重新打开shell时,用户
消失了
这是在一个类似prod的环境中,有一个适当的后台数据库。如果我降级Django 2.2.8->2.1.7,问题就会消失
>>> u = User(id=123131323122, first_name='hi', last_name='sup', email='test@mysupertest.com')
>>> u.set_password('foobar')
>>> u.save()
>>> User.objects.count()
1059790
>>> u.refresh_from_db()
>>> u
<User: test@mysupertest.com>
>>> cursor.execute("select * From my_users_table_name where id=123131323122")
1
now exiting InteractiveConsole...
myuser$ python manage.py shell
Python 3.6.9 (default, Nov 23 2019, 07:02:27)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from mypackage.models import User
>>> User.objects.count()
1059789
>>> User.objects.get(email='test@mysupertest.com')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 408, in get
self.model._meta.object_name
mypackage.models.User.DoesNotExist: User matching query does not exist.
>>> from django.db import connection
>>> cursor = connection.cursor(
>>> cursor.execute("select * From my_users_table_name where id=123131323122")
0
>>u=User(id=123131323122,first\u name='hi',last\u name='sup',email='sup'test@mysupertest.com')
>>>u.set_密码('foobar')
>>>u.save()
>>>User.objects.count()
1059790
>>>u.从_db()刷新_
>>>u
>>>cursor.execute(“从my_users_table_name中选择*,其中id=123131323122”)
1.
现在退出InteractiveConsole。。。
myuser$python manage.py shell
Python 3.6.9(默认值,2019年11月23日,07:02:27)
[GCC 6.3.0 20170516]在linux上
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
(InteractiveConsole)
>>>从mypackage.models导入用户
>>>User.objects.count()
1059789
>>>User.objects.get(email=)test@mysupertest.com')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/local/lib/python3.6/site packages/django/db/models/manager.py”,第82行,在manager\u方法中
返回getattr(self.get_queryset(),name)(*args,**kwargs)
get中第408行的文件“/usr/local/lib/python3.6/site packages/django/db/models/query.py”
self.model.\u meta.object\u name
mypackage.models.User.DoesNotExist:用户匹配查询不存在。
>>>从django.db导入连接
>>>cursor=connection.cursor(
>>>cursor.execute(“从my_users_table_name中选择*,其中id=123131323122”)
0
MyUser
继承自django的AbstractUser
,不重写save
或任何其他方法
事务自动提交的2.2更改肯定有问题。如果我用transaction.atomic()将save包装在
块中,那么它会正确提交。这不是一个可接受的解决方法,因为我不会包装每个用户.save()
调用我的代码库。我在数据库中有默认的AUTOCOMMIT=True
有两种方法可以解决这个问题
- 设置mysqld
paramautocommit=1
(如果您在AWS上,则设置db-param组)
- 设置
数据库[…]['OPTIONS']['init_command']='Set autocommit=1'
问题的根本原因是在数据库级别,autocommit=0
与数据库中的autocommit=True
不一致
A至在2.2中:
Django不再总是在执行单个查询时启动事务
正在执行,例如Model.save()、QuerySet.update()和
Model.delete()。这通过
减少数据库往返次数
在我的例子中,发生的是像.save()
和.update()
这样的单个查询不再被放入事务块中,因此不会发送COMMIT
语句
由于数据库端禁用了autocommit
,因此save()
不会保留在存储中。在shell级别,我们仍然在事务中,因此可以很好地看到对象,但在关闭shell之后,事务被丢弃,这就是为什么第二个shell看不到更改的原因