首页 文章

适当的sqlalchemy用于烧瓶

提问于
浏览
1

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

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

2 回答

  • 2

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

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

    但是,在Flask-SQLAlchemy的情况下,它有很多代码,还有一些黑魔法,关于与Flask上下文和修改跟踪以及持续时间调试交织的作用域会话以及一些在Web应用程序和所有可能的极端情况和其他一些事情中有用的东西 . 我有点过度工作了 . 我不是说你不应该使用它 - 只是从扩展代码开始看不到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)
    

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

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

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

    广告应用程序架构:对于更大的应用程序,最好使用Larger Applications patternsblueprints . 因此我的所有烧瓶路径处理程序都将在蓝图中,然后我将有一个"main"函数 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 app教程,链接到她详细介绍文件结构和db实现的部分 .

    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/

相关问题