2015-11-12 9 views
8

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.

Trả lời

3

Một phiên bản mới của django-pyodbc-xanh đã được xuất bản mà sửa chữa vấn đề này đối với tôi (cảm ơn bạn, Michaya). Để khắc phục, chỉ cần nâng cấp:

pip install django-pyodbc-azure==1.8.6 

... và cập nhật các tệp yêu cầu của bạn bất cứ khi nào cần thiết.Chi tiết tại đây: https://github.com/michiya/django-pyodbc-azure/issues/46

2

Vì nó hoạt động trên 7.0 và 7.1, tôi tự hỏi nếu cơ sở dữ liệu SQL Server 2014 của bạn được đặt ở mức tương thích SQL Server 2000, điều này sẽ hạn chế bạn sử dụng TDS phiên bản 7.1 trở xuống.

Links:

TDS Versions

Product Behavior

+0

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

Các vấn đề liên quan