2017-04-17 114 views
1

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

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

+2

http://flask-sqlalchemy.pocoo.org/ – davidism

回答

2

当然已经有一个烧瓶e xtension Flask-SQLAlchemy - 也在Flask文档SQLAlchemy in Flask中提到。但是像大多数Flask扩展一样,它所做的只是将一些“管道”Flask和SQLAlchemy(或任何其他库)集中在一起。最好的文档往往是时代的源代码:)

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

然而,在烧瓶SQLAlchemy中的情况下,大量的代码,并与有关瓶的背景和修改跟踪和交织范围的会议一些黑魔法持续时间调试以及一些在网络应用和所有可能的角落案例和其他一些事情中有用的东西。我会说这有点过分。我是而不是,表示你不应该使用它 - 只是从扩展代码首先看SQLAlchemy和Flask之间的连接是不可见的,所以它可能需要更多的阅读时间。

但是,如果你想自己做这很容易(当然,如容易为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) 

见我的例子瓶+ SQLAlchemy的应用: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。所以我所有的烧瓶路由处理程序都将在蓝图中,然后我将有一个“主”功能get_app() 1)创建Flask对象2)用它注册蓝图3)创建SQLAlchemy引擎并使用Flask app.before_request挂接Session()。大致类似于thisthis


,你应该永远只能有一个引擎

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

但是,当然会话连接到一个引擎。所以你需要多个会话。并且为您的示范课程提供多个声明性基础,并且 - 最重要的是 - 不会意外地混淆它。这就是为什么建议只有一个引擎 - 如果可能的话。

您可以为每个请求创建引擎 - 它在技术上是正确的,但效率不高。为整个应用程序保留一个引擎,并只为每个请求创建会话。

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

下面是一个有点联系更加通用但是也可以详细的步行通关于建立与瓶一SQLAlchemy的数据库,同时也越过使用ORM的查询,而不是原始的SQL查询的一些例子(虽然我一般使用原始的SQL查询 - 因为我平时也安装MySQL &在MySQL中创建工作台表,但是这只是使用API​​数据)可能是矫枉过正的应用程序:

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