关于python:flask-sqlalchemy或sqlalchemy

flask-sqlalchemy or sqlalchemy

我对flask和sqlacalchemy都是新手,我刚开始开发flask应用程序,现在我正在使用sqlacalchemy。我想知道使用flask sqlacchemy和sqlacchemy是否有任何显著的好处。我在http://packages.python.org/flask-sqlacalchemy/index.html中找不到足够的动机,或者我可能不理解它的价值!!非常感谢你的澄清。


Flask-SQLAlchemy的主要功能是与flask应用程序适当集成—它创建和配置引擎、连接和会话,并将其配置为与flask应用程序一起使用。

这个设置非常复杂,因为我们需要创建作用域会话并根据flask应用程序请求/响应生命周期正确地处理它。

在理想世界中,这将是Flask-SQLAlchemy的唯一特征,但实际上它增加了很少的东西。下面是一篇很好的博客文章,概述了它们:解开瓶子的神秘化。

当我第一次使用flask和sqlacalchemy时,我不喜欢头顶上的这个。我查看并从扩展中提取了会话管理代码。虽然我发现很难正确地进行集成,但这种方法还是有效的。

因此,更简单的方法(在我正在研究的另一个项目中使用)就是将Flask-SQLAlchemy放进去,不要使用它提供的任何附加功能。您将拥有db.session,并且您可以像使用纯SQLAlchemy设置一样使用它。


说实话,我看不出有什么好处。imho,flask sqlAlchemy创建了一个不需要的额外层。在我们的例子中,我们有一个相当复杂的flask应用程序,它使用ORM和core,具有多个数据库/连接(master-slave),其中,除其他外,我们需要控制会话/db事务(例如,dryrun和commit模式)。flask sqlAlchemy添加了一些额外的功能,比如自动销毁会话,假设您需要的某些东西通常不是您需要的。


sqlAlchemy文档清楚地说明您应该使用flask sqlAlchemy(特别是如果您不了解它的好处!):

[...] products such as Flask-SQLAlchemy [...] SQLAlchemy strongly recommends that these products be used as available.

这句话和一个详细的动机,你可以在第二个问题的会话常见问题。


flask sqlAlchemy为您提供了许多不错的额外功能,否则您最终将使用sqlAlchemy实现自己。

关于使用烧瓶的正面

  • flask_sqlAlchemy为您处理会话配置、设置和拆卸。
  • 为您提供使查询和分页更容易的声明性基础模型
  • 后端特定设置。flask-sqlachemy扫描安装的libs以获得Unicode支持,如果失败,则自动使用sqlachemy unicode。
  • 具有一个名为apply_driver_hacks的方法,该方法自动将sane默认值设置为thigs,如mysql池大小
  • 有很好的内置方法create_all()和drop_all(),用于创建和删除所有表。对于测试和在python命令行中有用,如果您做了一些愚蠢的事情
  • 它为您提供了get_或_404()而不是get()和find_或_404()而不是find()代码示例,位于>http://flask-sqlacalchemy.pocoo.org/2.1/queries/
  • 自动设置表名。flask sqlAlchemy自动设置您的表名转换您的ClassName>class_name,这可以通过设置__tablename__类来覆盖。列表项

    使用烧瓶的反面

  • 使用烧瓶SQL炼金术将使从烧瓶迁移到金字塔,如果你需要的话。这主要是由于flask_sqlachemy上的自定义声明性基础模型。
  • 使用flask sqlAlchemy,您可能会冒险使用一个社区比sqlAlchemy本身小得多的包,我不能很快从活动开发中删除它。
  • 如果你不知道它们在那里,一些很棒的额外的瓶子会让你困惑。

  • 正如@schlamar所暗示的,烧瓶的炼金术是一件好事。我只是想在这里添加一些额外的上下文。

    不要觉得你在选择一个而不是另一个。例如,假设我们想要使用flask sqlAlchemy模型从表中获取所有记录。它就像

    1
    Model.query.all()

    对于很多简单的情况,烧瓶的炼金术是完全好的。我想说的另外一点是,如果flask sqlAlchemy不能做你想做的,那么你就没有理由不能直接使用sqlAlchemy。

    1
    2
    3
    4
    5
    from myapp.database import db

    num_foo = db.session.query(func.count(OtherModel.id)).filter(is_deleted=False).as_scalar()

    db.session.query(Model.id, num_foo.label('num_foo')).order_by('num_foo').all()

    如您所见,我们可以轻松地从一个跳到另一个,而无需麻烦,在第二个示例中,我们实际上使用的是flask-sqlAlchemy定义的模型。


    下面是一个受益烧瓶的例子,sqlAlchemy提供了一个简单的sqlAlchemy。

    假设您正在使用flask_user。

    Flask_用户自动创建和验证用户对象,因此需要访问您的数据库。类用户管理器通过调用称为"适配器"的东西来实现这一点,该适配器抽象数据库调用。在UserManager构造函数中提供适配器,适配器必须实现以下功能:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class MyAdapter(DBAdapter):
        def get_object(self, ObjectClass, id):
           """ Retrieve one object specified by the primary key 'pk'"""
            pass

        def find_all_objects(self, ObjectClass, **kwargs):
            """ Retrieve all objects matching the case sensitive filters in 'kwargs'."""
            pass


        def find_first_object(self, ObjectClass, **kwargs):
           """ Retrieve the first object matching the case sensitive filters in 'kwargs'."""
            pass

        def ifind_first_object(self, ObjectClass, **kwargs):
           """ Retrieve the first object matching the case insensitive filters in 'kwargs'."""
            pass

        def add_object(self, ObjectClass, **kwargs):
           """ Add an object of class 'ObjectClass' with fields and values specified in '**kwargs'."""
            pass

        def update_object(self, object, **kwargs):
           """ Update object 'object' with the fields and values specified in '**kwargs'."""
            pass

        def delete_object(self, object):
           """ Delete object 'object'."""
            pass

        def commit(self):
            pass

    如果使用flask sqlachemy,则可以使用内置的sqlachemyadapter。如果您使用的是sqlAlchemy(而不是flask sqlAlchemy),那么您可能会对对象保存到数据库的方式(如表名)做出不同的假设,因此您必须编写自己的适配器类。