19

私のdjangoアプリケーションユニットテストの1つが失敗します

DatabaseError: ORA-00942: table or view does not exist

このエラーの原因となった実際のSQLクエリを確認したいと思います。あなたはそれを達成する方法を知っていますか?

4

9 に答える 9

19

テストからのすべてのSQLクエリを印刷/ログに記録する場合は、次のTestCaseようにサブクラス化してみてください。

from django.conf import settings
from django.template import Template, Context
import sys
from django.db import connection
from django.test import TestCase

class LoggingTestCase(TestCase):

  @staticmethod
  def setUpClass():
    # The test runner sets DEBUG to False. Set to True to enable SQL logging.
    settings.DEBUG = True
    super(LoggingTestCase, LoggingTestCase).setUpClass()

  @staticmethod
  def tearDownClass():
    super(LoggingTestCase, LoggingTestCase).tearDownClass()

    time = sum([float(q['time']) for q in connection.queries])
    t = Template("{{count}} quer{{count|pluralize:\"y,ies\"}} in {{time}} seconds:\n\n{% for sql in sqllog %}[{{forloop.counter}}] {{sql.time}}s: {{sql.sql|safe}}{% if not forloop.last %}\n\n{% endif %}{% endfor %}")
    print >> sys.stderr, t.render(Context({'sqllog': connection.queries, 'count': len(connection.queries), 'time': time}))

    # Empty the query list between TestCases.    
    connection.queries = []

次に、LoggingTestCase代わりにTestCaseテストの基本クラスとして使用します。tearDownClassオーバーライドする場合は、これを呼び出すことを忘れないでください。

于 2013-08-28T09:39:13.047 に答える
18

もう1つのオプションは、を使用することですCaptureQueriesContext(でテスト済みpytest)。

from django.db import connection
from django.test.utils import CaptureQueriesContext


def test_foo():
    with CaptureQueriesContext(connection) as ctx:
        # code that runs SQL queries
        print(ctx.captured_queries)

出典:

于 2020-02-19T11:31:04.340 に答える
9

次の手順を実行してクエリを取得することもできます(たとえば、印刷したり、テストで評価したりできます)。

実は最近は変えてはいけないdjango.conf.settingsoverride_settingsので、使っています。

from django.db import connection, reset_queries
from django.test import override_settings, TransactionTestCase

class TransactionTests(TransactionTestCase):

    @override_settings(DEBUG=True)
    def test_sql(self):
        reset_queries()
        try:
            # Code that uses the ORM goes here
        except Exception as e:
            pass
        self.assertEqual(connection.queries, [])

TestCaseまた、適切かもしれません。この回答の違いを参照してください。

SQL出力の​​詳細については、Djangoのドキュメントを参照してください。

于 2018-04-19T09:33:54.513 に答える
6

別のオプションはconnection.execute_wrapper()、次のようにテストで使用することです。

from django.db import connection

def logger(execute, sql, params, many, context):
    print(sql, params)
    return execute(sql, params, many, context)

class GizmoTest(TestCase):

    def test_with_sql_logging(self):
        with connection.execute_wrapper(logger):
            code_that_uses_database()

Django2.2でテスト済み。

于 2019-07-13T17:42:31.417 に答える
2

これは最もクリーンなソリューションではありませんが、追加のパッケージをインストールせずにすばやくデバッグしたい場合は、django / dbでexecute()メソッドを探すことができます。

Oracleの場合、次のようになります。

django / db / backends / oracle / base.pyを探して、次を探します。

def execute

PostgreSQLの場合は次のようになります。

django / db / backends / postgresql_psycopg2 / base.py

CursorWrapperには、execute()メソッドがあります。

どちらもIntegrityErrorとDatabaseErrorをキャッチしているので、そこにprintステートメントを追加できます。

すべてのSQLクエリを確認したいpplの場合は、関数呼び出しの直後にprintステートメントを配置します。

于 2013-08-30T04:56:41.120 に答える
1

の場合、pytestそれpytest-djangoのためのフィクスチャを作成するだけです

@pytest.fixture
def debug_queries(db):
    """ Because pytest run tests with DEBUG=False
        the regular query logging will not work, use this fixture instead
    """
    from django.db import connection
    from django.test.utils import CaptureQueriesContext
    with CaptureQueriesContext(connection):
        yield connection

その後、あなたのテストで

@pytest.mark.django_db
def test__queries(debug_queries):
    # run your queries here

もちろん、ロギング設定では、次のようなクエリのロギングを有効にする必要があります。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '%(asctime)s - %(levelname)s - %(name)s - %(message)s',
        },
    },
    'handlers': {
        'default': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'standard',
            'stream': 'ext://sys.stdout',
        },
    },
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['default'],
            'propagate': False,
        },
    }
}
于 2020-08-25T02:13:04.537 に答える
0

私がこれまでに見つけた最善の解決策は、django-debugtoolbarが提供するdebugsqlshellカスタムdjango管理コマンドです。

于 2012-11-26T11:53:38.873 に答える
0

設定でコンソールレベルをDEBUGに変更できます。Django1.9で動作しました。

LOGGING = {
...
'handlers': {
    'console': {
        'level': 'DEBUG',
        'class': 'logging.StreamHandler',
        'formatter': 'simple'
        },
    }
...
}
于 2017-08-22T05:53:21.363 に答える
0

これは私のために働いた解決策でした(Django3.1):

from django.test import TestCase


class TestSomething(TestCase):
    @override_settings(DEBUG=True)
    def test_something(self):
        pass
    
    def tearDown(self):
        from django.db import connection
        for query in connection.queries:
            print(f"✅ {query['sql']}\n")

ソース

于 2020-09-22T10:01:21.197 に答える