Создание таблиц с отношением бросков внешнего ключа не существует - PullRequest
0 голосов
/ 21 мая 2019

У меня есть приложение Peewee 3.6 (с колбой), которое использует базу данных Postgresql 11.Во время создания моделей, использующих create_tables, БД выдает relation "table" does not exist, если есть внешний ключ, упомянутое отношение которого еще не создано.Как настроить базу данных или peewee, чтобы они игнорировались во время инициализации базы данных или создавали FK позже, изменяя процесс?

Вот как я подключаюсь к базе данных:

from playhouse.pool import PooledPostgresqlExtDatabase
from playhouse.pool import PooledSqliteDatabase

def database_init(app, models):
    logging.info("Init database connection: %s %s" % (app.config["DATABASE"], app.config["DATABASE_NAME"]))
    if app.config["DATABASE"] == "postgresql":
        database = PooledPostgresqlExtDatabase(app.config["DATABASE_NAME"], max_connections=16, stale_timeout=300, **app.config["DATABASE_AUTH"])

    elif app.config["DATABASE"] == "sqlite":
        database = PooledSqliteDatabase(app.config["DATABASE_PATH"], pragmas={
            "journal_mode": "wal",
            "cache_size": -1024 * 64,
            "foreign_keys": 1
        })
    else:
        raise RuntimeError("No database set or invalid")
    try:
        DB.initialize(database)
    except:
        logging.exception("Could not initialize database")


def database_connect():
    try:
        DB.connect()
    except:
        logging.exception("Could not connect to database")

Где app.config["DATABASE_AUTH"] содержит только необходимые поля user, password, host и port.Функция database_connect вызывается позже остальной частью приложения.

Первоначальное создание таблицы не похоже на простое:

def create_tables(app, models):
    try:
        DB.create_tables(models, safe=True)
    except:
        logging.exception("Could not create tables")

Где models - списокмодели, собранные по порядку инициализации из разных модулей, например, не в порядке зависимости.

Моя самая сложная модель использует самоссылку, но большинство моих моделей просто имеет поле owner, которое ссылается на users.

Для самой первой модели это даетошибка, подобная этой, включая оператор create:

STATEMENT:  CREATE TABLE IF NOT EXISTS "category" ("id" SERIAL NOT NULL PRIMARY KEY, "created" TIMESTAMP NOT NULL, "edited" TIMESTAMP NOT NULL, "is_deleted" BOOLEAN NOT NULL, "owner_id" INTEGER, "name" TEXT NOT NULL, "comment" TEXT NOT NULL, "is_archived" BOOLEAN NOT NULL, "is_protected" BOOLEAN NOT NULL, "order" INTEGER NOT NULL, "path" TEXT NOT NULL, "parent_id" INTEGER, FOREIGN KEY ("owner_id") REFERENCES "user" ("id"), FOREIGN KEY ("parent_id") REFERENCES "category" ("id"))

ERROR:  current transaction is aborted, commands ignored until end of transaction block

Однако моя модель выглядит так для этого конкретного запроса, включая все ссылающиеся классы:

class BaseModel(peewee.Model):
    """ Peewee's Base model
    """
    class Meta:
        database = DB

class BaseUser(BaseModel):
    """ Base model for user
    """
    class Meta:
        table_name = "users"  # 'user' is reserved in most of dbs
    name = peewee.TextField(null=False, unique=True)
    password = peewee.TextField(null=False)
    pass

class BaseDocumentModel(BaseModel):
    created = peewee.DateTimeField(null=False, default=datetime.now)
    edited = peewee.DateTimeField(null=False, default=datetime.now, index=True)
    is_deleted = peewee.BooleanField(null=False, default=False)

    owner = peewee.ForeignKeyField(BaseUser, null=True)

    def changed(self):
        self.edited = datetime.now()

class Category(components.BaseDocumentModel):
    name = peewee.TextField()
    comment = peewee.TextField(default="")
    is_archived = peewee.BooleanField(default=False)
    is_protected = peewee.BooleanField(default=False)
    order = peewee.IntegerField(default=0)
    path = peewee.TextField()
    parent = peewee.ForeignKeyField("self", backref="children", null=True)

...