sql >> データベース >  >> RDS >> PostgreSQL

複数のPostgresスキーマでDjangoユニットテストが失敗する

    スキーマは、他の多くのDBエンジンでは使用されていません。モデルにスキーマを指定することで、postgresのコードに依存関係を導入しました。

    問題を解決するために取ることができる2つのルートがあります;

    まず、postgresユーザーにデフォルトの検索パスを追加できます。このアプローチの欠点は、スキーマを名前空間に使用できなくなることですが、データベースが別のエンジンに変更された場合でも、コードが正常に機能するという利点があります。テーブルの名前空間は、Djangoがデフォルトで行う方法と同様に、テーブルに名前を付ける標準的な方法を選択することで実現できます(例:appName_className)

    これを実現するには2つの方法があります。この方法でそれを行うpostgresコマンドは次のとおりです:

    ALTER USER (your user) SET search_path = "$user",(schema1),(schema2),(schema3),(...)
    

    それを行うためのdjangoのみの方法は次のとおりです:

    # Warning! This is untested, I just glanced at the docs and it looks right.
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            # some configuration here
            'OPTIONS': {
                'options': '-c search_path=schema1,schema2,schema3'
            }
        }
    }
    

    また、変更する必要があります:

    db_table = 'cedirData\".\"persons'
    

    宛先:

    db_table = 'persons'
    

    ボーナスとして、次のものを使用できるようになりました:

    manage.py inspectdb > models.py
    

    これは優れた機能であり、既存のデータベースを手動でコピーする必要はありません。

    ただし、スキーマの名前空間がデータベースで頻繁に使用され、他のアプリケーションがそれに依存している場合、このソリューションは役に立ちません。別のアプローチは、テストデータベースにそれらのスキーマを作成するカスタムテストランナーを作成することです。これは、上記のアプローチよりもやや複雑で、面倒な場合があります。これを行うことはあまりお勧めしませんが、興味があればお手伝いできます。

    それほど面倒ではありませんが、より「ハッキー」な方法は、テストの実行時にメタを単純にオーバーライドすることです。これもテストランナーになります。

    from django.test.simple import DjangoTestSuiteRunner
    from django.db.models.loading import get_models
    
    class SchemaModelTestRunner(DjangoTestSuiteRunner):
        """Docstring"""
        def setup_test_environment(self, *args, **kwargs):
            self.original_db_tables = {}
            self.schema_models = [m for m in get_models()
                                     if '"."' in m._meta.db_table]
            for m in self.schema_models:
                schema, table = m._meta.db_table.split('"."')
                self.original_db_tables[m] = m._meta.db_table
                m._meta.db_table = 'schema_'+schema+'_table_'+table
    
            super(SchemaModelTestRunner, self).setup_test_environment(*args,
                                                                       **kwargs)
        def teardown_test_environment(self, *args, **kwargs):
            super(SchemaModelTestRunner, self).teardown_test_environment(*args,
                                                                          **kwargs)
            # reset models
            for m in self.schema_models:
                m._meta.db_table = self.original_db_tables[m]
    

    また、settings.pyファイルでこれをテストランナーとして定義することもできます。




    1. PHP-MYSQL内で結果を関連付けてフェッチする際の問題

    2. Postgresql-データベースをバックアップし、別の所有者に復元しますか?

    3. PHPでMysql行を反復処理します

    4. 親子関係でソフト削除をカスケードする方法