Flask和SQLAlchemy以及MetaData对象 [英] Flask and SQLAlchemy and the MetaData object

查看:292
本文介绍了Flask和SQLAlchemy以及MetaData对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次使用这个环境。

我愿意使用的SQLAlchemy部分只是一个允许使用autoload = True的Table对象来查询数据库的部分。我这样做是因为我的表已经存在于数据库(MySQL服务器),并没有通过定义瓶模型创建。



我已经通过了所有的文档,我不似乎找不到答案。这里有一些代码:

$ $ p $ $ $ $ $ $
$ b metadata = None

def connect_db():
engine = create_engine(app.config ['DATABASE_URI'])
全局元数据
metadata =元数据(绑定=引擎)
返回engine.connect()


@ app.before_request
def before_request():
g.db = connect_db ()


@ app.teardown_request
def teardown_request(例外):
g.db.close()

现在您可能想知道为什么我使用全局变量名称元数据。还有一些代码:

$ p $ @ app.route('/ test /< int:id>')
def test(test_result_id):

testTable = Table('test_table',metadata,autoload = True)

正如你可以看到我需要该对象是全球性的,以便从一个函数内访问它。

另外我声明相同的变量testTable中的每个函数都需要它。我觉得这不是正确的做法。

感谢所有!

解决方案

你见过

也许这会工作:

pre > #作为一个全局的全局
metadata = MetaData()

@ app.before_first_request
def autoload_tables():
meta .reflect(bind = g.db.bind)

@ app.route('/')
def index():
users_table = meta.tables ['users' ]

这样,您的表只在每个进程中反映一次,这可能就是您想要的。请注意,您的引擎也应该是一个全球性的,所以你不需要在@ app.before_request中创建一个新的引擎 - 创建应用程序是一个更合适的地方。如果你的情况非常特殊,你可能需要每个请求一个引擎,在这种情况下,你应该考虑 /en/rel_0_8/core/schema.html#sqlalchemy.schema.ThreadLocalMetaDatarel =nofollow> ThreadLocalMetaData class。


it's the first time i am using this environment.

The part of SQLAlchemy i am willing to use is just the one that allows me to query the database using Table objects with autoload = True. I am doing this as my tables already exist in the DB (mysql server) and were not created by defining flask models.

I have gone through all the documentation and i don't seem to find an answer. Here is some code:

app = Flask(__name__)
app.config.from_object(__name__)

metadata = None

def connect_db():
    engine = create_engine(app.config['DATABASE_URI'])
    global metadata
    metadata = MetaData(bind=engine)
    return engine.connect()


@app.before_request
def before_request():
    g.db = connect_db()


@app.teardown_request
def teardown_request(exception):
    g.db.close()

Now you could be wondering why i use that global var named metadata. Ok some more code:

@app.route('/test/<int:id>')
def test(test_result_id):

    testTable = Table('test_table', metadata , autoload=True)

As you can see i need that object to be global in order to access it from within a function.

Also I am declaring the same var testTable in each function that needs it. I have the feeling this is not the right approach. I coudn't find any best practice advice for a case like mine.

Thanks all!

解决方案

Have you seen this snippet in the SQLAlchemy docs?

Maybe this would work:

# This is fine as a global global
metadata = MetaData()

@app.before_first_request
def autoload_tables():
    meta.reflect(bind=g.db.bind)

@app.route('/')
def index():
    users_table = meta.tables['users']

That way your tables are reflected only once per process which is probably what you want. Note that your engine should be a global too, so you needn't create a new engine in @app.before_request - app creation is a more appropriate place.

If your case is very special you might need one engine per request, in which case you should consider the ThreadLocalMetaData class.

这篇关于Flask和SQLAlchemy以及MetaData对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆