Ran*_*don 7 mysql django xampp mysql-python savepoints
我们正在尝试自定义 User 模型和行为,但随后我们注意到,即使是默认的 Django 安装在通过 Django Admin 添加新用户时也会出现问题:
该问题甚至在其他 Django 版本中也会发生(在 Django 1.8和最新版本 Django 1.11.3 中尝试过)。令人惊讶的是,使用 SQLite 或 PostgreSQL 数据库时不会发生此问题。此外,通过$./manage.py createuser
和 以编程方式添加用户将起作用。admin
通过终端编辑现有用途(如先前创建的超级用户)也将起作用。Group 的 CRUD 机制按预期工作,因此只有Add User
视图会受到影响。
可能的故障点包括Django 核心(任何版本)、MySQL 二进制文件(捆绑在 XAMPP for Mac 中,也尝试过各种版本)或MySQL-Python连接器(版本 1.2.5)。类似的问题在这里,使用 Django 1.10和 MySQL。
复制步骤:
安装最新的 Django 版本:
$ pip install django
安装 Python-MySQL 驱动程序:
$ pip install MySQL-python
创建一个新项目:
$ django-admin.py startproject sandbox
在 MySQL 中创建一个新数据库并在其中设置 db 配置 settings.py
迁移 Django 应用程序的模型:
$ ./manage.py migrate
创建admin
超级用户:
$ ./manage.py createsuperuser
运行 Django 的捆绑服务器:
$ ./manage.py runserver
转到http://127.0.0.1:8000/admin/login
,并使用admin
超级用户凭据登录。
尝试单击用户的添加按钮。屏幕截图中附加的错误将被触发。
示例数据库查询日志:
Query SET NAMES utf8
Query set autocommit=1
Query SELECT `django_session`.`session_key`, `django_session`.`session_data`, `django_session`.`expire_date` FROM `django_session` WHERE (`django_session`.`session_key` = 'ikql6mk9voxq4g0go9avuvuxxrpvwx9w' AND `django_session`.`expire_date` > '2017-07-10 06:58:15.823513')
Query SELECT `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`id` = 1
Query SAVEPOINT `s123145414516736_x1`
Query RELEASE SAVEPOINT `s123145414516736_x1`
Query ROLLBACK TO SAVEPOINT `s123145414516736_x1`
Query rollback
Query set autocommit=1
Quit
Run Code Online (Sandbox Code Playgroud)
似乎在 SAVEPOINT RELEASE 之后 SAVEPOINT ROLLBACK 已经完成,导致 SAVEPOINT 丢失。基于MySQL 的 SavePoint 文档,自然顺序似乎是 ROLLBACK 然后 RELEASE。
这是回溯消息。settings.py
除了用于连接到 MySQL 服务器的数据库配置/凭据外,Django 的默认设置没有其他更改:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/auth/user/add/
Django Version: 1.11.3
Python Version: 2.7.8
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
551. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
149. response = view_func(request, *args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
224. return view(request, *args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
67. return bound_func(*args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
76. return view(request, *args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
63. return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
67. return bound_func(*args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
149. response = view_func(request, *args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
63. return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/contrib/auth/admin.py" in add_view
103. return self._add_view(request, form_url, extra_context)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/contrib/auth/admin.py" in _add_view
131. extra_context)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view
1508. return self.changeform_view(request, None, form_url, extra_context)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
67. return bound_func(*args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
149. response = view_func(request, *args, **kwargs)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
63. return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/contrib/admin/options.py" in changeform_view
1408. return self._changeform_view(request, object_id, form_url, extra_context)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/db/transaction.py" in __exit__
210. connection.savepoint_rollback(sid)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/db/backends/base/base.py" in savepoint_rollback
348. self._savepoint_rollback(sid)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/db/backends/base/base.py" in _savepoint_rollback
308. cursor.execute(self.ops.savepoint_rollback_sql(sid))
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
80. return super(CursorDebugWrapper, self).execute(sql, params)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
65. return self.cursor.execute(sql, params)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/db/utils.py" in __exit__
94. six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
63. return self.cursor.execute(sql)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/django/db/backends/mysql/base.py" in execute
101. return self.cursor.execute(query, args)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/MySQLdb/cursors.py" in execute
205. self.errorhandler(self, exc, value)
File "/Users/ranelpadon/.virtualenvs/django__1_11/lib/python2.7/site-packages/MySQLdb/connections.py" in defaulterrorhandler
36. raise errorclass, errorvalue
Exception Type: OperationalError at /admin/auth/user/add/
Exception Value: (1305, 'SAVEPOINT s123145452511232_x1 does not exist')
Run Code Online (Sandbox Code Playgroud)
这个错误困扰了我很长时间,所以我决定进一步挖掘并尝试一劳永逸地解决它。
根本原因:SAVEPOINT 问题是仅在MySQL-Python
连接器中发生的错误。
修复:为 Python 使用其他 MySQL 驱动程序(例如mysqlclient
)。
详情/调查结果:
libmysqlclient.18.dylib
) 和 5.7 ( libmysqlclient.20.dylib
)。通过改变 MySQL 二进制文件/版本没有发现任何关系。但是我通过测试 Python 中常用的各种 MySQL 驱动程序缩小了问题的范围:
MySQLdb(广泛使用但旧的数据库连接器,最后一次提交是在 7 年前!):
$ pip install MySQL-python
mysqlclient(现代版本MySQL-python
,但有很多错误修复和改进):
$ pip install mysqlclient
PyMySQL(纯 Python MySQL 数据库驱动程序):
$ pip install PyMySQL
然后,添加settings.py
(就在 下方import os
):
try:
import pymysql
pymysql.install_as_MySQLdb()
except:
pass
Run Code Online (Sandbox Code Playgroud)Oracle 的MySQL-Connector-Python(纯 Python MySQL 数据库驱动程序):
$ pip install mysql-connector-python-rf
然后,编辑数据库的ENGINE
配置settings.py
:
'ENGINE': 'mysql.connector.django',
Run Code Online (Sandbox Code Playgroud)SAVEPOINT 问题仅在使用MySQL-python连接器(#1 驱动程序)时发生,而在其他(#2、#3、#4 驱动程序)中不会发生。就我而言,我选择了mysqlclient。现在问题消失了。
归档时间: |
|
查看次数: |
1114 次 |
最近记录: |