我正在开发一个使用 FastAPI、SQLAlchemy、Pydantic/psycopg2 和 Uvicorn 堆栈的 Python 应用程序。该项目的结构类似于 FastAPI 在
fastapi[dot]tiangolo[dot]com/tutorial/bigger-applications/
的“更大的应用程序 - 多个文件”,其中创建了名为 Base
的 SQLAlchemy 元数据,其中包含应用程序的所有表以及名为 的 SQLAlchemy 引擎对象engine
。在主函数中,我然后调用:
Base.metadata.create_all(bind=engine)
由
uvicorn
bash 命令运行。
当使用单个 ASGI Worker 运行此应用程序时,第一次启动没问题,但我注意到,如果我尝试使用多个 Worker(即
--workers 4
),其中一些会尝试在第一次启动之前执行此调用调用者已标记元数据已创建,这会导致错误:
sqlalchemy.exc.IntegrityError: (psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint "pg_class_relname_nsp_index"
DETAIL: Key (relname, relnamespace)=(accounts_id_seq, 2200) already exists.
[SQL:
CREATE TABLE accounts (
id SERIAL NOT NULL,
PRIMARY KEY (id)
)
]
(Background on this error at: https://sqlalche.me/e/20/gkpj)
这不一定是意外的,但也是不受欢迎的。完整的堆栈跟踪可以在
github[dot]com/mwhicks-dev/pyacct/issues/15
找到。
我可以在第一次使用干净的 Postgre DB 时使用一个工作人员运行我的服务器,但这似乎更像是一种解决方法,而不是解决方案。
我忽略的这个问题有解决办法吗?
checkfirst
标志可以传递给 create_all
.,即。 create_all(bind=engine, checkfirst=True)
如果您每次部署时都重建数据库,那可能会起作用。 尽管这不会检测到对现有表的更改:
如果您需要随着时间的推移不断改进您的应用程序和数据库(正常情况),那么您可能需要运行
alembic
将数据库升级到最新版本,作为部署过程的一部分。 在最初的情况下,将构建所有表。