【发布时间】:2016-09-29 14:30:21
【问题描述】:
有什么方法可以将我的 Flask-SQLAlchemy 模型导入 Jupyter 笔记本?我希望能够在笔记本中探索我的模型和数据。
【问题讨论】:
-
其实我今天测试过了。它工作得很好。
标签: python flask flask-sqlalchemy jupyter-notebook
有什么方法可以将我的 Flask-SQLAlchemy 模型导入 Jupyter 笔记本?我希望能够在笔记本中探索我的模型和数据。
【问题讨论】:
标签: python flask flask-sqlalchemy jupyter-notebook
我还没有尝试过,但我相信它可以通过一些工作来完成。
导入应用程序db,以及您要使用的模型。在进行查询之前推送应用程序上下文。如果你理解了这一切,你就完成了。
在设置您的 Flask 应用程序的代码中,您有一个 Flask-SQLAlchemy 对象,通常定义如下:
from flask_sqlalchemy import FlaskSQLAlchemy
db = FlaskSQLAlchemy()
在其他地方你有你的模型:
from db_setup import db
class MyThing(db.Model):
thing_id = db.Column(db.Integer())
还有更远的地方你有应用程序:
from flask import Flask
from db_setup import db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = '...'
db.init_app(app)
现在,在您的 iPython 笔记本中,您必须能够导入上面的最后两部分:
from app_setup import app
from models import MyThing
要运行查询,您必须在应用上下文中(请参阅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()
您应该能够在那里运行任何查询。如果我没记错的话,即使在with 块之外,things 中的对象仍然有效,您可以检索它们的属性等。
如果你想显式提交,你可以从定义的地方导入db,然后做
db.session.commit()
就像使用模型类名进行查询一样,db 只能在上下文中工作。
不要担心这部分,除非你已经完成了上述工作,但你想调整你是如何做到的。
首先,您可能不想使用以与在 Flask 代码中创建应用完全相同的方式创建的应用。例如,您可能想要使用不同的配置。无需导入定义 app 的模块,您只需在笔记本中创建一个新的 Flask 应用程序即可。你仍然需要导入db(做db.init_app(app))和MyThing。但是这些模块可能没有任何配置代码,因为配置都是在应用程序级别完成的。
其次,除了使用with,您还可以明确地这样做
my_context = app.app_context()
my_context.push()
然后是你的 SQLAlchemy 代码,然后是
my_context.pop()
这有两个好处。您可以只推送一次上下文,然后在多个笔记本单元格中使用它。 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
最后一个考虑因素是,使用 vanilla SQLAlchemy 而不是 FlaskSQLAlchemy 定义模型可能是有意义的。这意味着您不需要使用上下文的所有内容,只需要一个数据库连接来创建会话。这将使在非 Flask 代码中导入模型变得更加容易,但代价是它会使在 Flask 中使用它们变得更加困难。
【讨论】: