适当的sqlalchemy用于烧瓶

时间:2017-04-17 20:36:27

标签: python flask sqlalchemy

我正在为烧瓶和sqlalchemy的funsies制作基本API。我在sqlalchemy文档中读到,你应该只有一个带有连接字符串的引擎。应该如何在应用程序中构建>一个__init__.py文件?在烧瓶文件中运行以启动烧瓶服务器?这是我的github回购,因为我认为更容易看到当前的应用程序结构和它可能有的任何缺陷。 https://github.com/JayHelton/Geekdom_Web_App

在我的查询方法中,我每次创建一个新的数据库引擎,它似乎正在工作,但如果有多个人试图调用这些方法,我不想遇到问题。谢谢!

2 个答案:

答案 0 :(得分:2)

当然已经存在Flask扩展Flask-SQLAlchemy - Flask docs SQLAlchemy in Flask中也提到过。但是像大多数Flask扩展一样,它所做的只是"只是"一些"管道" Flask和SQLAlchemy(或任何其他库)在一起。最好的文档往往是源代码:)

github.com/mitsuhiko/flask-sqlalchemy/blob/master/flask_sqlalchemy/__init__.py

然而,在Flask-SQLAlchemy的情况下,它有很多代码,还有一些黑魔法,关于与Flask上下文和修改跟踪以及持续时间调试交织在一起的作用域会话以及一些在Web应用程序和所有可能的极端情况和其他一些情况下有用的东西的东西。我说它有点过度工程了。我表示你不应该使用它 - 只是首先从扩展代码看不到SQLAlchemy和Flask之间的连接,因此可能需要更多的阅读时间。

但是如果你想自己做这件事很容易(好吧,因为 easy 就像SQLAlchemy所能得到的那样) - 只需初始化SQLAlchemy就可以获得sessionmaker,然后创建一个在每个请求之前进行会话,然后在请求之后不要忘记关闭:)并且只在Flask处理程序中使用此会话(我的意思是@app.route函数)。

import flask
import sqlalchemy
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class Item (Base):

    __tablename__ = 'items'

    id = Column(Integer, primary_key=True)
    title = Column(String)    

engine = sqlalchemy.create_engine('sqlite:///bestappever.db', echo=True)
Session = sessionmaker(bind=engine)

# create all tables if you wish...
Base.metadata.create_all(engine)

app = flask.Flask(__name__)

@app.before_request
def create_session():
    flask.g.session = Session()

@app.teardown_appcontext
def shutdown_session(response_or_exc):
    flask.g.session.commit()
    flask.g.session.remove()

@app.route('/')
    # just use the SQLAlchemy session :)
    items = flask.g.session.query(Item).all()
    return flask.render_template('index.html', items=items)

请参阅我的示例Flask + SQLAlchemy app:https://github.com/messa/db-workshop-web-app/blob/sqlalchemy/anketa.py

如您所见,您甚至可以将所有内容放在一个大文件上,但将其拆分为多个文件(其中一个通常命名为model.py) 是最好的做法。

最重要的是在各个请求之间进行隔离会话 - 在我的解决方案中,为before_request挂钩中的每个请求创建会话。来自Flask docs "SQLAlchemy in Flask"的解决方案使用scoped_session,它具有基本相同的效果(使用线程局部变量实现,每个线程有一个单独的会话)。

广告应用程序架构:对于更大的应用程序,最好使用Larger Applications patternsblueprints。所以我所有的烧瓶路线处理程序都将在蓝图中,然后我会有一个" main"函数get_app() 1)创建Flask对象2)向其注册蓝图3)创建SQLAlchemy引擎并使用Flask Session()挂钩app.before_request。与thisthis大致相似。

  

你应该只有一个引擎

为什么呢?从技术上讲,引擎只是数据库的连接(池)。如果您的应用程序使用三个独立的数那么你当然需要三个引擎。

但是当然会话只与一个引擎相关联。所以你需要多个会话。并且为您的模型类提供了多个声明性基础,并且 - 最重要的是 - 不会意外混淆。这就是为什么建议只使用一个引擎 - 如果可能的话。

您可以根据请求创建引擎 - 技术上是正确的,但效率低下。为整个应用程序保留一个引擎,只需为每个请求创建会话。

答案 1 :(得分:0)

在Flask应用程序上安装SQLAlchemy后,您需要创建一个单独的* .py文件来存储数据库配置,并使用import语句将其合并到您要使用的其他.py文件中。

如果您想在应用程序本身中查看/创建API数据表,它们将存在于' models.py'文件,它还导入数据库连接字符串。

这是一个非常好的Flask + SQLAlchemy todo应用教程,链接到她详细描述文件结构和数据库实现的部分。

http://www.vertabelo.com/blog/technical-articles/web-app-development-with-flask-sqlalchemy-bootstrap-part-2

下面是一个更通用的链接,但也有关于使用Flask设置SQLAlchemy数据库的详细步骤,还介绍了使用ORM查询而不是原始SQL查询的几个示例(尽管我通常使用原始SQL查询 - 假设我通常也在MySQL工作台中安装MySQL和创建表,但对于仅使用API​​数据的应用程序来说这可能有点过分了):

http://flask.pocoo.org/docs/0.12/patterns/sqlalchemy/