Python 炼金术还是炼金术

Python 炼金术还是炼金术,python,flask,orm,sqlalchemy,flask-sqlalchemy,Python,Flask,Orm,Sqlalchemy,Flask Sqlalchemy,我对flask和sqlalchemy都是新手,我刚刚开始开发一个flask应用程序,现在我正在使用sqlalchemy。我想知道使用flask sqlalchemy和sqlalchemy是否有什么显著的好处。我找不到足够的动机,或者我不理解它的价值!!非常感谢您的澄清。SQLAlchemy文档明确指出,您应该使用Flask SQLAlchemy(特别是如果您不了解它的好处!): […]产品,如Flask SQLAlchemy[…]SQLAlchemy强烈建议在可用时使用这些产品 这句话和你可以在

我对flask和sqlalchemy都是新手,我刚刚开始开发一个flask应用程序,现在我正在使用sqlalchemy。我想知道使用flask sqlalchemy和sqlalchemy是否有什么显著的好处。我找不到足够的动机,或者我不理解它的价值!!非常感谢您的澄清。

SQLAlchemy文档明确指出,您应该使用Flask SQLAlchemy(特别是如果您不了解它的好处!):

[…]产品,如Flask SQLAlchemy[…]SQLAlchemy强烈建议在可用时使用这些产品


这句话和你可以在第二个问题中找到的详细动机。

老实说,我没有看到任何好处。哦,炼金术创造了一个你并不真正需要的额外层。在我们的例子中,我们有一个相当复杂的Flask应用程序,它有多个数据库/连接(主从),同时使用ORM和Core,其中,我们需要控制会话/DB事务(例如,dryrun和commit模式)。Flask SQLAlchemy添加了一些附加功能,例如自动销毁会话,假设您需要的东西往往不是您所需要的。

正如@schlamar建议的那样,Flask SQLAlchemy是一件好事。我只是想在这里提出的观点上添加一些额外的内容


不要觉得你在选择一个而不是另一个。例如,假设我们想要使用使用Flask Sqlalchemy的模型从表中获取所有记录。这很简单

Model.query.all()
对于很多简单的案例,炼金术是完全可以的。我想说的另一点是,如果Sqlalchemy不能做你想做的事情,那么没有理由不能直接使用Sqlalchemy

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定义的模型。

这里是Flask Sqlalchemy比普通Sqlalchemy给您带来好处的示例

假设您正在使用flask\u用户

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

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 sqlalchemy,那么可以使用内置的SQLAlchemyAdapter。如果您使用的是sqlalchemy(不是flask sqlalchemy),您可能会对对象保存到数据库的方式(如表名)做出不同的假设因此,您必须编写自己的适配器类。

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

此设置非常复杂,因为我们需要创建并根据Flask应用程序请求/响应生命周期正确处理它

在理想世界中,这将是炼金术的唯一特征,但实际上,它并没有增加更多的东西。查看更多信息。或者看这篇博文,并对他们进行了概述:(更新:原文目前不可用,有一个)

当我第一次使用Flask和SQLAlchemy时,我不喜欢这种开销。我从扩展中提取了会话管理代码。尽管我发现很难正确地进行这种集成,但这种方法仍然有效


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

Flask-SQLAlchemy为您提供了许多额外的功能,否则您将使用SQLAlchemy实现自己的功能

炼金术的积极面
  • Flask_SQLAlchemy为您处理会话配置、设置和拆卸
  • 为您提供了使查询和分页更容易的声明性基本模型
  • 后端特定设置。Flask-SQLAlchemy扫描已安装的libs以获得Unicode支持,如果失败,则自动使用SQLAlchemy Unicode
  • 有一个名为
    apply\u driver\u hacks
    的方法,可以自动将sane默认值设置为MySQL池大小之类的值
  • 有很好的内置方法create_all()和drop_all()来创建和删除所有表。如果您做了一些愚蠢的事情,那么在python命令行中对测试和测试非常有用
  • 它为您提供get_或_404()而不是get(),以及find_或_404()而不是find()代码示例,位于>
  • 自动设置表名。Flask SQLAlchemy会自动设置表名转换您的
    类名
    类名
    这可以通过设置
    \uuuuuuu表名
    类来覆盖 列表项

    炼金术的负面影响
  • 使用炼金术会增加额外的困难 从烧瓶迁移到金字塔,如果需要的话。这主要是由于Flask_SQLAchemy上的自定义声明性基础模型
  • 使用Flask SQLAlchemy,您可能会面临使用一个比SQLAlchemy本身社区小得多的包的风险,我不能很快从活动开发中放弃它
  • 如果你不知道炼金术有一些额外的东西,它们会让你感到困惑

  • 是的,在您的用例中,炼金术似乎过时了。但是如果OP有这样的情况,他可能不会问这个问题。对于一个对会话范围一无所知的新用户来说,SQLAlchemy绝对是必须的!炼金术似乎无法维持。最后一次更新是在2013年8月1日。这个建议还有什么意义吗?@pmav99,只要你没有混凝土