简体   繁体   English

在Jupyter笔记本中使用Flask-SQLAlchemy模型

[英]Use Flask-SQLAlchemy models in Jupyter notebook

Is there any way I can import my Flask-SQLAlchemy models into a Jupyter notebook? 有什么办法可以将我的Flask-SQLAlchemy模型导入到Jupyter笔记本中吗? I would like to be able to explore my models and data in the notebook. 我希望能够在笔记本中探索我的模型和数据。

I haven't tried this but I believe it can be done, with a little bit of work. 我没有尝试过,但我相信可以通过一些工作来完成。


tl;dr TL;博士

Import the app, db , and the models you want to use. 导入app, db和要使用的模型。 Push the app context before doing a query. 在执行查询之前推送应用程序上下文。 If you understood all this, you're done. 如果你理解了这一切,你就完成了。


In more detail 更详细

In the code which sets up your Flask app, you have a Flask-SQLAlchemy object, which is usually defined something like this: 在设置Flask应用程序的代码中,您有一个Flask-SQLAlchemy对象,通常定义如下:

from flask_sqlalchemy import FlaskSQLAlchemy
db = FlaskSQLAlchemy()

And somewhere else you have your models: 在其他地方你有你的模型:

from db_setup import db
class MyThing(db.Model):
    thing_id = db.Column(db.Integer())

And further somewhere you have the app: 在某个地方你有应用程序:

from flask import Flask
from db_setup import db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = '...'
db.init_app(app)

Now, in your iPython notebook you have to be able to import the last two pieces above: 现在,在您的iPython笔记本中,您必须能够导入上面的最后两个部分:

from app_setup import app
from models import MyThing

To run a query, you have to be in the app context (see http://flask.pocoo.org/docs/1.0/api/#flask.Flask.app_context ): 要运行查询,您必须在应用程序上下文中(请参阅http://flask.pocoo.org/docs/1.0/api/#flask.Flask.app_context ):

with app.app_context():
    things = MyThing.query.filter(MyThing.thing_id < 100).all()

You should be able to run any query there. 您应该能够在那里运行任何查询。 If I remember correctly, even outside of the with block the objects in things will still be valid, and you can retrieve their properties, etc. 如果我没记错的话,即使在with块之外, things的对象仍然有效,你可以检索它们的属性等。

If you want to explicitly commit, you can import db from where it's defined, and do 如果要显式提交,可以从定义的位置导入db ,然后执行

db.session.commit()

Just like using the model class name to make a query, db only works inside a context. 就像使用模型类名进行查询一样, db只能在上下文中工作。


Technicalities 技术性

Don't worry about this section unless you got the above working but you want to tweak how you did it. 除非你完成了上述工作,否则不要担心这一部分,但你想调整你的工作方式。

First of all, you might not want to use an app created in exactly the same way that you create it in your Flask code. 首先,您可能不想使用以与在Flask代码中创建它的方式完全相同的方式创建的应用程序。 For example, you might want to use a different config. 例如,您可能希望使用其他配置。 Instead of importing the module where app is defined, you could just create a new Flask app in your notebook. 您可以在笔记本中创建一个新的Flask应用程序,而不是导入定义app的模块。 You still have to import db (to do db.init_app(app) ) and MyThing . 您仍然需要导入db (执行db.init_app(app) )和MyThing But these modules probably don't have any configuration code in, since the configuration is all done at the level of the app. 但是这些模块可能没有任何配置代码,因为配置都是在应用程序级别完成的。

Secondly, instead of use with , you could also explicitly do 其次,代替使用with ,你也可以明确地做

my_context = app.app_context()
my_context.push()

then your SQLAlchemy code, and then later 然后你的SQLAlchemy代码,然后再

my_context.pop()

This has two advantages. 这有两个好处。 You can just push the context once, before using it in multiple notebook cells. 在将其用于多个笔记本单元格之前,您可以将上下文推送一次。 The with block only works inside one cell. with块仅适用于一个单元格。

Furthermore, storing the context in a variable after creating it means that you can re-use the same context. 此外,在创建变量后将上下文存储在变量中意味着您可以重用相同的上下文。 For the purposes of SQLAlchemy, the context acts a bit like a transaction. 出于SQLAlchemy的目的,上下文有点像事务。 If you make a change to an object in one context, they won't apply in another context, unless you committed to the database. 如果在一个上下文中对对象进行更改,则它们将不会应用于其他上下文,除非您已提交到数据库。 If you store a FlaskSQLAlchemy object in a Python variable, you won't be able to do anything with it inside a different context. 如果将FlaskSQLAlchemy对象存储在Python变量中,则无法在不同的上下文中对其执行任何操作。

You could also store the context in a variable, then use it in multiple with blocks. 您还可以存储上下文中的变量,然后在多用它with块。

my_context = app.app_context()
with my_context.push():
    thing1 = MyThing.query().order_by(MyThing.thing_id).first()

# (Maybe in another cell)
with my_context.push()
    print thing1.thing_id

A last consideration, is that it might make sense to define your models using vanilla SQLAlchemy instead of FlaskSQLAlchemy. 最后一个考虑因素是,使用vanilla SQLAlchemy而不是FlaskSQLAlchemy定义模型可能是有意义的。 This would mean that you wouldn't need all the stuff above using contexts, just a database connection to create a session. 这意味着您不需要使用上下文的所有内容,只需要数据库连接来创建会话。 This would make it much easier to import the models in non-flask code, but the tradeoff would be that it would make using them in Flask a bit harder. 这将使得在非烧瓶代码中导入模型变得更加容易,但是权衡的是它会使得在Flask中使用它们更加困难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM