Flask-SQLAlchemy如何将create_all与schema_translate_map一起使用

时间:2017-02-15 18:32:23

标签: python sqlalchemy flask-sqlalchemy

SQLAlchemy提供了Connection.execution_options.schema_translate_map来更改执行时间中的模式,如docs中所述。

在示例中显示了如何使用执行查询,但想知道如何将其与create_all()一起使用。

我正在使用Flask-Sqlaclhemy和postgresql作为数据库。假设我有这个:

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

def create_app():
    app = Flask(...)
    ...
    db.init_app(app)
    ...
    return app

class User(db.Model):
    __tablename__ = 'user'
    __talbe_args__ = {'schema':'public'}
    company = db.Column(db.String(10))

class SomePublicModel(db.Model):
    __tablename__ = 'some_public'
    __talbe_args__ = {'schema':'public'}
    ...

class SomeModelByDynamicSchema(db.Model):
    __tablename__ = 'some_dynamic'
    __talbe_args__ = {'schema':'dynamic'}
    ...

dynamic架构将根据用户公司的执行时间替换其他值。

假设我已经在数据库中有模式publicdynamic,并且我想用表创建一个新的模式,如下所示:

def create_new():
    user = User(company='foo')
    db.session.execute("CREATE SCHEMA IF NOT EXISTS %s" % user.company)
    db.session.connection().execution_options(schema_translate_map={'dynamic':user.company})

    #I would like to do something of the kind
    db.create_all() 

我希望在foo模式中创建表为foo.some_dynamic,但SQLAlchemy仍尝试在dynamic模式中创建。

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

设置执行选项时,可以创建连接副本。这意味着create_all在没有schema_translate_map的情况下运行。

>>> c = Base.session.connection()
>>> w = c.execution_options(schema_translate_map={'dynamic':'kek'})
>>> c._execution_options
immutabledict({})
>>> w._execution_options
immutabledict({'schema_translate_map': {'dynamic': 'kek'}})

答案 1 :(得分:0)

要实现您的目标,您可以尝试另一种方法。

从旧语法中获取表格并适应新的元数据。

metadata = MetaData(bind=engine, schema=db_schema)
for table in db.Model.metadata.tables.values():
    table.tometadata(metadata)
metadata.drop_all()
metadata.create_all()