0

Djangoプロジェクト用にPostgreでいくつかのテーブルを手動で作成しました。私も手動でモデルを作成しました。しようとするとsyncdb、データベースエラーがスローされ、テーブルがすでに存在していると表示されます。

syncdbが以前にテーブルを作成した場合、これは発生しません。syncdbは、テーブルを作成したかどうか、またはテーブルを作成したかどうかをどのように認識しますか?

4

1 に答える 1

1

djangoはアプリとそのモデルの内部キャッシュを維持しているようです。ここから、モデルのテーブルがすでに作成されているかどうかがわかります。これがイントロスペクションがサポートされている理由であり、モデルは既存のスキーマから作成され、キャッシュは適切に設定されていると思います。

syncdbソースから、 syncdbで何を行う必要があるかを理解するためのプロセスが何であるかは明らかです。

    # Get a list of already installed *models* so that references work right.
    tables = connection.introspection.table_names()
    seen_models = connection.introspection.installed_models(tables)
    created_models = set()
    pending_references = {}

    # Build the manifest of apps and models that are to be synchronized
    all_models = [
        (app.__name__.split('.')[-2],
            [m for m in models.get_models(app, include_auto_created=True)
            if router.allow_syncdb(db, m)])
        for app in models.get_apps()
    ]

    def model_installed(model):
        opts = model._meta
        converter = connection.introspection.table_name_converter
        return not ((converter(opts.db_table) in tables) or
            (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables))

    manifest = SortedDict(
        (app_name, list(filter(model_installed, model_list)))
        for app_name, model_list in all_models
    )

各データベースドライバには、テーブル名をフェッチするためのコードがあります。これはpostgresql用です:

def get_table_list(self, cursor):
        "Returns a list of table names in the current database."
        cursor.execute("""
            SELECT c.relname
            FROM pg_catalog.pg_class c
            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
            WHERE c.relkind IN ('r', 'v', '')
                AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
                AND pg_catalog.pg_table_is_visible(c.oid)""")
        return [row[0] for row in cursor.fetchall()]
于 2013-05-06T06:02:15.207 に答える