Django syncdb - Как он узнает, создал ли он ранее таблицы или сделал это я?

Я вручную создал несколько таблиц в Postgre для проекта Django. Я тоже создал модель вручную. Когда я пытаюсь syncdb, он выдает ошибку базы данных и говорит, что таблица уже существует.

Если syncdb создаст таблицу ранее, этого не произойдет. Как syncdb узнает, создал ли он таблицу или я создал ее?


person colboynik    schedule 11.03.2013    source источник
comment
Почему вы создаете таблицы вручную? Если вам нужно иметь исходные данные в вашей базе данных, вы должны использовать фикстуры   -  person toto_tico    schedule 11.03.2013
comment
Нет никакой разницы между созданием таблицы syncdb и ее созданием вами. Однако Syncdb не очень умен, когда речь идет о промежуточных таблицах, например, для ManyToManyField. Можете ли вы опубликовать модель и код sql?   -  person Greg    schedule 11.03.2013
comment
@toto_tico Я уже давно создал таблицы. Я подумал, что есть лучший способ сделать это, но мне просто интересно, как syncdb узнает, была ли таблица, которая оказалась там, созданной им или мной. Я не знал о приспособлениях. Спасибо за указатель.   -  person colboynik    schedule 27.03.2013
comment
@Greg Если нет разницы, почему syncdb жалуется, что таблицы уже существуют. Разве он не должен предположить, что это был тот, кто их создал?   -  person colboynik    schedule 27.03.2013
comment
@JohnRambo, прочитайте остальную часть моего комментария, пожалуйста...   -  person Greg    schedule 28.03.2013
comment
@Greg Я не опубликовал свой код, потому что я довольно сильно его изменил с тех пор, как опубликовал это изначально, и только неделю назад понял, как использовать git. Хотя я не думаю, что это имеет значение. Если вы вручную создадите таблицу, а затем создадите соответствующую модель, syncdb сообщит, что таблица уже существует. Откуда он знает?, особенно если он такой простой. Это уже не так важно, поскольку Юг может это понять. Мне просто интересно сейчас. Спасибо!   -  person colboynik    schedule 03.04.2013
comment
Что вы имеете в виду, когда говорите I manually created the model too   -  person Burhan Khalid    schedule 06.05.2013
comment
Я выполнил операторы SQL с помощью psql.   -  person colboynik    schedule 25.05.2013


Ответы (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()]
person Burhan Khalid    schedule 06.05.2013