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

Sta*_*tan 6 python flask flask-sqlalchemy jupyter-notebook

有什么办法可以将我的Flask-SQLAlchemy模型导入到Jupyter笔记本中吗?我希望能够在笔记本中探索我的模型和数据.

jwg*_*jwg 6

我还没有尝试过这个,但我相信它可以完成,只需做一点工作。


tl;博士

导入应用程序、db和您要使用的模型。在执行查询之前推送应用程序上下文。如果你理解了这一切,你就大功告成了。


更详细

在设置 Flask 应用程序的代码中,您有一个 Flask-SQLAlchemy 对象,它通常定义如下:

from flask_sqlalchemy import FlaskSQLAlchemy
db = FlaskSQLAlchemy()
Run Code Online (Sandbox Code Playgroud)

在其他地方你有你的模型:

from db_setup import db
class MyThing(db.Model):
    thing_id = db.Column(db.Integer())
Run Code Online (Sandbox Code Playgroud)

更远的地方你有这个应用程序:

from flask import Flask
from db_setup import db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = '...'
db.init_app(app)
Run Code Online (Sandbox Code Playgroud)

现在,在您的 iPython 笔记本中,您必须能够导入上面的最后两部分:

from app_setup import app
from models import MyThing
Run Code Online (Sandbox Code Playgroud)

要运行查询,您必须处于应用程序上下文中(请参阅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()
Run Code Online (Sandbox Code Playgroud)

您应该能够在那里运行任何查询。如果我没记错的话,即使在with块之外,其中的对象things仍然有效,您可以检索它们的属性等。

如果你想明确提交,你可以db从它定义的地方导入,然后做

db.session.commit()
Run Code Online (Sandbox Code Playgroud)

就像使用模型类名进行查询一样,db只能在上下文中工作。


技术性

不要担心这一部分,除非你已经完成了上述工作,但你想调整你的工作方式。

首先,您可能不想使用以与在 Flask 代码中创建的方式完全相同的方式创建的应用程序。例如,您可能想要使用不同的配置。app您可以在笔记本中创建一个新的 Flask 应用程序,而不是导入定义的模块。您仍然必须导入db(执行db.init_app(app))和MyThing. 但是这些模块可能没有任何配置代码,因为配置都是在应用程序级别完成的。

其次,with你也可以明确地做,而不是使用

my_context = app.app_context()
my_context.push()
Run Code Online (Sandbox Code Playgroud)

然后是您的 SQLAlchemy 代码,然后是

my_context.pop()
Run Code Online (Sandbox Code Playgroud)

这有两个优点。您可以只推送一次上下文,然后在多个笔记本单元格中使用它。该with块仅在一个单元格内起作用。

此外,在创建后将上下文存储在变量中意味着您可以重复使用相同的上下文。就 SQLAlchemy 而言,上下文的行为有点像事务。如果您在一个上下文中对对象进行更改,则它们不会应用于另一个上下文,除非您提交给数据库。如果您将 FlaskSQLAlchemy 对象存储在 Python 变量中,您将无法在不同的上下文中对其进行任何操作。

您还可以将上下文存储在一个变量中,然后在多个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
Run Code Online (Sandbox Code Playgroud)

最后一个考虑是,使用 vanilla SQLAlchemy 而不是 FlaskSQLAlchemy 来定义模型可能是有意义的。这意味着您不需要使用上下文的上述所有内容,只需要一个数据库连接来创建会话。这将使在非烧瓶代码中导入模型变得更容易,但权衡是它会使在 Flask 中使用它们变得更加困难。