Ror*_*art 22 python postgresql sqlalchemy
我有一个带有架构参数的SqlAlchemy模型,如下所示:
Base = declarative_base()
class Road(Base):
__tablename__ = "roads"
__table_args__ = {'schema': 'my_schema'}
id = Column(Integer, primary_key=True)
Run Code Online (Sandbox Code Playgroud)
当我使用Base.metadata.create_all(engine)时,它正确地在前面发出一个带有模式名称的CREATE TABLE,就像这样"CREATE TABLE my_schema.roads("但Postgresql正确地抱怨模式不存在.
我错过了让SqlAlchemy发布CREATE SCHEMA my_schema的步骤,还是我必须手动调用它?
Ror*_*art 30
我已经在我的db init脚本上手动完成了它,如下所示:
from sqlalchemy.schema import CreateSchema
engine.execute(CreateSchema('my_schema'))
Run Code Online (Sandbox Code Playgroud)
但这似乎不像我期待的那么神奇.
vic*_*vic 17
我遇到了同样的问题,并认为发布DDL的"最干净"方式是这样的:
from sqlalchemy import event
from sqlalchemy.schema import CreateSchema
event.listen(Base.metadata, 'before_create', CreateSchema('my_schema'))
Run Code Online (Sandbox Code Playgroud)
这将确保在创建基础元数据中包含的任何内容之前,您具有该模式.但是,这不会检查架构是否已存在.
CreateSchema('my_schema').execute_if(callback_=check_schema)
如果你可以打扰编写check_schema
回调(文档中的" 控制DDL序列 " should_create
),你可以这样做.或者,作为一种简单的方法,只需使用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"))
Run Code Online (Sandbox Code Playgroud)
metadata.tables
您可以根据此 Github 问题评论进行迭代:
Run Code Online (Sandbox Code Playgroud)from sqlalchemy import event @event.listens_for(Base.metadata, "before_create") def create_schemas(target, connection, **kw): schemas = set() for table in target.tables.values(): if table.schema is not None: schemas.add(table.schema) for schema in schemas: connection.execute("CREATE SCHEMA IF NOT EXISTS %s" % schema) @event.listens_for(Base.metadata, "after_drop") def drop_schemas(target, connection, **kw): schemas = set() for table in target.tables.values(): if table.schema is not None: schemas.add(table.schema) for schema in schemas: connection.execute("DROP SCHEMA IF EXISTS %s" % schema)
[编辑前]
我编写了一个函数,根据接受的答案创建声明的模式。它使用每个映射类的__table_args__字典中的模式值。
from sqlalchemy import event
@event.listens_for(Base.metadata, "before_create")
def create_schemas(target, connection, **kw):
schemas = set()
for table in target.tables.values():
if table.schema is not None:
schemas.add(table.schema)
for schema in schemas:
connection.execute("CREATE SCHEMA IF NOT EXISTS %s" % schema)
@event.listens_for(Base.metadata, "after_drop")
def drop_schemas(target, connection, **kw):
schemas = set()
for table in target.tables.values():
if table.schema is not None:
schemas.add(table.schema)
for schema in schemas:
connection.execute("DROP SCHEMA IF EXISTS %s" % schema)
Run Code Online (Sandbox Code Playgroud)
为什么他们不会默认创建模式,根据Michael Bayers对此Github 问题的评论:
[..]不幸的是,“模式”的概念在数据库之间的移植性不太好。在 MySQL 中,没有“CREATE SCHEMA”;只有其他数据库,例如用户帐户通常无权执行的“CREATE DATABASE”,此外还有许多与创建数据库相关的其他参数。在 SQLite 中,没有“CREATE SCHEMA”,您可以附加单独的文件。在 Oracle 中,没有“CREATE SCHEMA”,还有其他充当命名空间的用户帐户,它们同样具有非常不同的权限/语法,此外还有可以引用其他类型对象(例如远程表空间等)的同义词。只有 Postgresql 和 SQL Server 将“schema”链接到(通常)对应于“CREATE SCHEMA”的名称,即使如此,这些名称也可能是其他名称的符号名称,因为您可以将点符号和其他表达式放入“schema”中”。
使用元数据添加“CREATE SCHEMA”的简单方法只是一个简单的事件,并且可以将其添加到文档中 [...]
归档时间: |
|
查看次数: |
12558 次 |
最近记录: |