8

Linux でしばらくの間、django-pyodbc-azure を pydobc、FreeTDS、および unixODBC とともに使用して、Django を SQL Server 2014 に接続しました。正常に動作していたアプリケーションでこの問題に遭遇し、デバッグで問題が発生しました。それ。問題を再現するために、新しい Django アプリを開始して物事をシンプルに保ちました。これが私の仮想環境です:

(azuretest)[vagrant@vagrant azuretest]$ pip freeze
Django==1.8.6
django-pyodbc-azure==1.8.3.0
pyodbc==3.0.10

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',
        },
    },
}

そして、単純な models.py を作成しました:

class TestTemp(models.Model):
    tempdate = models.DateField()

このセットアップは、かなり複雑な Django プロジェクトで正常に機能しており、この同じデータベースに対して引き続き SELECT を実行できます。ただし、UPDATE または移行を実行しようとすると、次のエラーが発生します。

(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 Server ([home_testtemp]) でテーブルを正常に作成し、不要なロールバックでエラーが発生しているように見えることです。これをさらにデバッグするか、問題を修正するための最良の方法についてのアイデアはありますか? ./manage.py sqlmigrate homeこのユーザー名とパスワードでログインしたデータベースに対して直接SQL 出力を実行すると、正常に動作します。

前もって感謝します。

更新 1: これは良い修正ではありませんが、ロールバックが呼び出されるべきではないときに呼び出されるという問題と思われるものを回避します。この変更は、django-pyodbc-azure の base.py の 389 行目付近で行われます。

これは見苦しく、セーフガードを取り除きますが、その間は機能します。django-pyodbc-azure の 389 行目付近の base.py を変更します。

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 に戻すことであり、これは明らかに修正に役立つ情報です。

4

2 に答える 2

3

この問題を修正する新しいバージョンの django-pyodbc-azure が公開されました (ありがとう、Michaya)。それを修正するには、単にアップグレードしてください:

pip install django-pyodbc-azure==1.8.6

...必要に応じて要件ファイルを更新します。詳細はこちら: https://github.com/michiya/django-pyodbc-azure/issues/46

于 2015-11-20T17:00:37.270 に答える