Tôi đã sử dụng django-pyodbc-azure trong một thời gian trên Linux, cùng với pydobc, FreeTDS và unixODBC để kết nối Django với SQL Server 2014. Tôi đã chạy vào vấn đề này với một ứng dụng đã hoạt động tốt và đang gặp sự cố khi gỡ lỗi nó. Để tái tạo vấn đề, tôi đã bắt đầu một ứng dụng Django hoàn toàn mới để giữ mọi thứ đơn giản. Dưới đây là virtualenv tôi:lỗi rollback django-pyodbc-azure với cấu hình làm việc trước đây - dòng 389
(azuretest)[[email protected] azuretest]$ pip freeze
Django==1.8.6
django-pyodbc-azure==1.8.3.0
pyodbc==3.0.10
Đây là cơ sở dữ liệu của tôi cấu hình để kết nối với SQL Server:
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',
},
},
}
Và tôi đã tạo ra một models.py đơn giản:
class TestTemp(models.Model):
tempdate = models.DateField()
này thiết lập đã làm việc tốt trong một dự án Django khá phức tạp, mà vẫn có thể SELECT để cùng một cơ sở dữ liệu. Tuy nhiên, bất cứ khi nào tôi cố gắng làm một UPDATE hoặc di cư, tôi đã nhận được lỗi này:
(azuretest)[[email protected] 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!')
Phần lạ là nó thành công tạo ra bảng trong SQL Server ([home_testtemp]), và có vẻ là lỗi trên một rollback không cần thiết. Bất kỳ ý tưởng nào về cách tốt nhất để gỡ lỗi thêm hoặc khắc phục sự cố này? Khi tôi chạy đầu ra SQL bằng ./manage.py sqlmigrate home
trực tiếp đối với cơ sở dữ liệu được đăng nhập bằng tên người dùng và mật khẩu này, nó hoạt động tốt.
Xin cảm ơn trước.
CẬP NHẬT 1: đây không phải là một sửa chữa tốt, nhưng được xung quanh những gì dường như là một vấn đề với một rollback được gọi là khi nó không nên. Thay đổi này được thực hiện xung quanh dòng 389 của base.py trong django-pyodbc-azure:
Điều này là xấu và loại bỏ một biện pháp bảo vệ, nhưng làm cho mọi thứ hoạt động trong thời gian chờ đợi. Sửa đổi base.py xung quanh dòng 389 trong django-pyodbc-xanh:
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
Rõ ràng, vẫn đang tìm kiếm một sửa chữa thực tế chứ không phải là một hack và nguyên nhân gốc rễ.
CẬP NHẬT 2: Hoàn nguyên thay đổi được thực hiện trong CẬP NHẬT 1 ở trên thành bản gốc django-pyodbc. Sau đó, trong CÀI ĐẶT, hãy thay đổi tds_version thành 7.0
hoặc 7.1
. Nó hoạt động. Nếu bạn thay đổi nó thành 7.2
hoặc 7.3
, nó sẽ bị hỏng. Đây có phải là vấn đề với các trường DATE mới có sẵn bắt đầu trong SQL Server 2008 không? Dù bằng cách nào, giải pháp tạm thời là hoàn nguyên về TDS phiên bản 7.1 và đây là thông tin hữu ích rõ ràng hướng tới bản sửa lỗi.
Cảm ơn bạn đã trả lời - rất tiếc, ở mức độ tương thích 120, được mặc định cho năm 2014. Nó đã hoạt động trước đó. Tôi không tin rằng năm 2014 (và có thể năm 2012) cho phép các cấp dưới 90, loại trừ khả năng SQL Server 7.0 hoặc 2000. – FlipperPA