先前工作配置的 django-pyodbc-azure 回滚错误 - 第 389 行
django-pyodbc-azure rollback error with previously working configuration - line 389
我在 Linux 上使用 django-pyodbc-azure 有一段时间了,连同 pydobc、FreeTDS 和 unixODBC 将 Django 连接到 SQL Server 2014。我 运行用一个运行良好的应用程序解决这个问题,但在调试它时遇到了麻烦。为了重现这个问题,我启动了一个 b运行d 新的 Django 应用程序来让事情变得简单。这是我的虚拟环境:
(azuretest)[vagrant@vagrant azuretest]$ pip freeze
Django==1.8.6
django-pyodbc-azure==1.8.3.0
pyodbc==3.0.10
这是我连接到 SQL 服务器的数据库配置:
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'HOST': 'myserver.com',
'PORT': '1433',
'NAME': 'my_db',
'USER': 'my_db_user',
'PASSWORD': 'mypw',
'AUTOCOMMIT': True,
'OPTIONS': {
'driver': 'FreeTDS',
'autocommit': True,
'unicode_results': True,
'host_is_server': True,
'extra_params': 'tds_version=7.2',
},
},
}
我创建了一个简单的 models.py:
class TestTemp(models.Model):
tempdate = models.DateField()
这个设置在一个相当复杂的 Django 项目中运行良好,它仍然可以 SELECT 到同一个数据库。但是,每当我尝试进行更新或迁移时,我都会收到此错误:
(azuretest)[vagrant@vagrant azuretest]$ ./manage.py migrate home
Operations to perform:
Apply all migrations: home
Running migrations:
Rendering model states... DONE
Applying home.0001_initial...Traceback (most recent call last):
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/sql_server/pyodbc/base.py", line 389, in _set_aut
ocommit
self.connection.rollback()
pyodbc.Error: ('HY000', 'The driver did not supply an error!')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/__init__.py", line 354, in
execute_from_command_line
utility.execute()
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/__init__.py", line 346, in
execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/base.py", line 394, in run
_from_argv
self.execute(*args, **cmd_options)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/base.py", line 445, in exe
cute
output = self.handle(*args, **options)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line
222, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/migrations/executor.py", line 110, in m
igrate
self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/migrations/executor.py", line 154, in a
pply_migration
self.recorder.record_applied(migration.app_label, migration.name)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/migrations/recorder.py", line 67, in re
cord_applied
self.migration_qs.create(app=app, name=name)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/models/query.py", line 348, in create
obj.save(force_insert=True, using=self.db)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/models/base.py", line 734, in save
force_update=force_update, update_fields=update_fields)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/models/base.py", line 759, in save_base
with transaction.atomic(using=using, savepoint=False):
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/transaction.py", line 186, in __enter__
connection.set_autocommit(False)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/backends/base/base.py", line 295, in se
t_autocommit
self._set_autocommit(autocommit)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/sql_server/pyodbc/base.py", line 390, in _set_aut
ocommit
self.connection.autocommit = autocommit
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/utils.py", line 98, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/utils/six.py", line 658, in reraise
raise value.with_traceback(tb)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/sql_server/pyodbc/base.py", line 389, in _set_aut
ocommit
self.connection.rollback()
django.db.utils.Error: ('HY000', 'The driver did not supply an error!')
奇怪的是,它在 SQL 服务器 ([home_testtemp]) 中成功创建了 table,并且似乎在不必要的回滚时出错。关于进一步调试或解决问题的最佳方法的任何想法?当我 运行 ./manage.py sqlmigrate home
输出的 SQL 直接针对使用此用户名和密码登录的数据库时,它工作正常。
提前致谢。
更新 1:这不是一个很好的修复,但解决了在不应该调用回滚时似乎出现的问题。此更改是在 django-pyodbc-azure 中 base.py 的第 389 行附近进行的:
这很丑陋并且摆脱了保护措施,但同时可以使事情正常进行。在 django-pyodbc-azure 中修改 base.py 大约第 389 行:
def _set_autocommit(self, autocommit):
self.connection.commit()
# with self.wrap_database_errors:
# if autocommit:
# self.connection.commit()
# else:
# self.connection.rollback()
# self.connection.autocommit = autocommit
显然,仍在寻找实际的修复方法而不是破解和根本原因。
更新 2:将上面更新 1 中所做的更改撤销到原始的 django-pyodbc。然后在设置中,将 tds_version 更改为 7.0
或 7.1
。有用。如果将其更改为 7.2
或 7.3
,它会中断。这可能是从 SQL Server 2008 开始可用的新 DATE 字段的问题吗?无论哪种方式,一个临时解决方案是恢复到 TDS 版本 7.1,这显然是对修复有用的信息。
因为它适用于 7.0 和 7.1,我想知道您的 SQL Server 2014 数据库是否设置为 SQL Server 2000 兼容级别,这会限制您使用 TDS 7.1 或更低版本。
链接:
新版本的 django-pyodbc-azure 已经发布,它为我解决了这个问题(谢谢你,Michaya)。要修复它,只需升级:
pip install django-pyodbc-azure==1.8.6
...并在必要时更新您的需求文件。详情在这里:https://github.com/michiya/django-pyodbc-azure/issues/46
我在 Linux 上使用 django-pyodbc-azure 有一段时间了,连同 pydobc、FreeTDS 和 unixODBC 将 Django 连接到 SQL Server 2014。我 运行用一个运行良好的应用程序解决这个问题,但在调试它时遇到了麻烦。为了重现这个问题,我启动了一个 b运行d 新的 Django 应用程序来让事情变得简单。这是我的虚拟环境:
(azuretest)[vagrant@vagrant azuretest]$ pip freeze
Django==1.8.6
django-pyodbc-azure==1.8.3.0
pyodbc==3.0.10
这是我连接到 SQL 服务器的数据库配置:
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'HOST': 'myserver.com',
'PORT': '1433',
'NAME': 'my_db',
'USER': 'my_db_user',
'PASSWORD': 'mypw',
'AUTOCOMMIT': True,
'OPTIONS': {
'driver': 'FreeTDS',
'autocommit': True,
'unicode_results': True,
'host_is_server': True,
'extra_params': 'tds_version=7.2',
},
},
}
我创建了一个简单的 models.py:
class TestTemp(models.Model):
tempdate = models.DateField()
这个设置在一个相当复杂的 Django 项目中运行良好,它仍然可以 SELECT 到同一个数据库。但是,每当我尝试进行更新或迁移时,我都会收到此错误:
(azuretest)[vagrant@vagrant azuretest]$ ./manage.py migrate home
Operations to perform:
Apply all migrations: home
Running migrations:
Rendering model states... DONE
Applying home.0001_initial...Traceback (most recent call last):
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/sql_server/pyodbc/base.py", line 389, in _set_aut
ocommit
self.connection.rollback()
pyodbc.Error: ('HY000', 'The driver did not supply an error!')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/__init__.py", line 354, in
execute_from_command_line
utility.execute()
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/__init__.py", line 346, in
execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/base.py", line 394, in run
_from_argv
self.execute(*args, **cmd_options)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/base.py", line 445, in exe
cute
output = self.handle(*args, **options)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line
222, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/migrations/executor.py", line 110, in m
igrate
self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/migrations/executor.py", line 154, in a
pply_migration
self.recorder.record_applied(migration.app_label, migration.name)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/migrations/recorder.py", line 67, in re
cord_applied
self.migration_qs.create(app=app, name=name)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/models/query.py", line 348, in create
obj.save(force_insert=True, using=self.db)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/models/base.py", line 734, in save
force_update=force_update, update_fields=update_fields)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/models/base.py", line 759, in save_base
with transaction.atomic(using=using, savepoint=False):
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/transaction.py", line 186, in __enter__
connection.set_autocommit(False)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/backends/base/base.py", line 295, in se
t_autocommit
self._set_autocommit(autocommit)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/sql_server/pyodbc/base.py", line 390, in _set_aut
ocommit
self.connection.autocommit = autocommit
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/db/utils.py", line 98, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/django/utils/six.py", line 658, in reraise
raise value.with_traceback(tb)
File "/home/vagrant/.virtualenvs/azuretest/lib/python3.4/site-packages/sql_server/pyodbc/base.py", line 389, in _set_aut
ocommit
self.connection.rollback()
django.db.utils.Error: ('HY000', 'The driver did not supply an error!')
奇怪的是,它在 SQL 服务器 ([home_testtemp]) 中成功创建了 table,并且似乎在不必要的回滚时出错。关于进一步调试或解决问题的最佳方法的任何想法?当我 运行 ./manage.py sqlmigrate home
输出的 SQL 直接针对使用此用户名和密码登录的数据库时,它工作正常。
提前致谢。
更新 1:这不是一个很好的修复,但解决了在不应该调用回滚时似乎出现的问题。此更改是在 django-pyodbc-azure 中 base.py 的第 389 行附近进行的:
这很丑陋并且摆脱了保护措施,但同时可以使事情正常进行。在 django-pyodbc-azure 中修改 base.py 大约第 389 行:
def _set_autocommit(self, autocommit):
self.connection.commit()
# with self.wrap_database_errors:
# if autocommit:
# self.connection.commit()
# else:
# self.connection.rollback()
# self.connection.autocommit = autocommit
显然,仍在寻找实际的修复方法而不是破解和根本原因。
更新 2:将上面更新 1 中所做的更改撤销到原始的 django-pyodbc。然后在设置中,将 tds_version 更改为 7.0
或 7.1
。有用。如果将其更改为 7.2
或 7.3
,它会中断。这可能是从 SQL Server 2008 开始可用的新 DATE 字段的问题吗?无论哪种方式,一个临时解决方案是恢复到 TDS 版本 7.1,这显然是对修复有用的信息。
因为它适用于 7.0 和 7.1,我想知道您的 SQL Server 2014 数据库是否设置为 SQL Server 2000 兼容级别,这会限制您使用 TDS 7.1 或更低版本。
链接:
新版本的 django-pyodbc-azure 已经发布,它为我解决了这个问题(谢谢你,Michaya)。要修复它,只需升级:
pip install django-pyodbc-azure==1.8.6
...并在必要时更新您的需求文件。详情在这里:https://github.com/michiya/django-pyodbc-azure/issues/46