我有一个SqlAlchemy模型,其中的schema参数如下所示:
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
的步骤,或者我必须手动调用它?
4条答案
按热度按时间w8ntj3qf1#
我已经在我的db init脚本上手动完成了它,如下所示:
但这似乎没有我想象的那么神奇。
hfyxw5xn2#
我也遇到了同样的问题,我相信发出DDL的“最干净”的方法是这样的:
这将确保在创建包含在基元数据中的任何内容之前,您已经拥有了它的模式。但是,这并不检查模式是否已经存在。
如果您愿意编写
check_schema
回调函数(文档中关于should_create
的“控制DDL序列”),您可以执行CreateSchema('my_schema').execute_if(callback_=check_schema)
。或者,作为一种简单的方法,使用DDL("CREATE SCHEMA IF NOT EXISTS my_schema")
代替(对于Postgres):nqwrtyyt3#
你可以迭代
metadata.tables
,根据这个Github问题评论:[编辑前]
我编写了一个函数,它根据接受的答案创建声明的模式。它使用每个Map类的**table_argsdict中的schema**值。
为什么他们不会默认创建模式,根据Michael Bayers对this Github问题的评论:
[..]不幸的是,“模式”的概念在数据库之间的移植性不是很好。在MySQL中,没有“CREATE SCHEMA”;只有其他的数据库E。例如,“创建数据库”,用户帐户通常没有访问权限,另外还有很多其他参数与创建数据库沿着使用。在SQLite中,没有“CREATE SCHEMA”,有单独的文件可以附加。在Oracle中,没有“CREATE SCHEMA”,有其他用户帐户充当命名空间,它们同样具有非常不同的权限/语法,此外,还有可以引用其他类型的对象的同义词,如远程表空间等。只有PostgreSQL和SQL Server将“schema”链接到对应于(通常)“CREATE SCHEMA”的名称,即使这样,这些名称也可能是其他东西的符号名称,因为您可以将虚线符号和其他表达式放入“schema”中。
将“CREATE SCHEMA”与元数据一起抛出的简单方法只是一个简单的事件,并且可以将其添加到docs [。..]
uklbhaso4#
这是the accepted answer(使用SQLAlchemy事件,看起来不错)和this more flexible answer的最佳组合,this more flexible answer不需要硬编码模式名称:
这将创建一个由表指定的模式,如下所示:
这很好用。
%(schema)s
,它会神奇地工作,因为我们正在响应Table
事件,但它没有。如果有人理解这部分文档的内容,我很乐意更新这个答案!*