我有一个使用Postgresql 11数据库的Peewee 3.6(带烧瓶)应用程序。在使用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)