[英]Getting SQLAlchemy to issue CREATE SCHEMA on create_all
我有一个带有架构参数的 SqlAlchemy 模型,如下所示:
Base = declarative_base()
class Road(Base):
__tablename__ = "roads"
__table_args__ = {'schema': 'my_schema'}
id = Column(Integer, primary_key=True)
当我使用Base.metadata.create_all(engine)
它会正确地发出一个CREATE TABLE
前面有架构名称,就像CREATE TABLE my_schema.roads (
但 Postgresql 正确地抱怨架构不存在。
我是否缺少让 SqlAlchemy 发出CREATE SCHEMA my_schema
的步骤,还是我必须手动调用它?
我已经在我的 db init 脚本上手动完成了,如下所示:
from sqlalchemy.schema import CreateSchema
engine.execute(CreateSchema('my_schema'))
但这似乎没有我预期的那么神奇。
我遇到了同样的问题,并相信发布 DDL 的“最干净”的方式是这样的:
from sqlalchemy import event
from sqlalchemy.schema import CreateSchema
event.listen(Base.metadata, 'before_create', CreateSchema('my_schema'))
这将确保在创建基础元数据中包含的任何内容之前,您已拥有它的架构。 但是,这不会检查模式是否已经存在。
你可以做CreateSchema('my_schema').execute_if(callback_=check_schema)
如果你可以打扰编写check_schema
回调(“ 控制 DDL 序列” on should_create
in docs)。 或者,作为一种简单的方法,只需使用DDL("CREATE SCHEMA IF NOT EXISTS my_schema")
代替(对于 Postgres):
from sqlalchemy import DDL
event.listen(Base.metadata, 'before_create', DDL("CREATE SCHEMA IF NOT EXISTS my_schema"))
我编写了一个函数,它根据接受的答案创建声明的模式。 它使用来自每个映射类的__table_args__ dict 的模式值。
from sqlalchemy import event, DDL
# Import or write your mapped classes and configuration here
def init_db():
for mapper in Base.registry.mappers:
cls = mapper.class_
if issubclass(cls, Base):
table_args = getattr(cls, '__table_args__', None)
if table_args:
schema = table_args.get('schema')
if schema:
stmt = f"CREATE SCHEMA IF NOT EXISTS {schema}"
event.listen(Base.metadata, 'before_create', DDL(stmt))
Base.metadata.create_all(bind=engine)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.