flask-sqlalchemy或sqlalchemy

我是烧瓶和sqlalchemy的新手,我刚刚开始烧瓶应用程序,现在我正在使用sqlalchemy。 我想知道使用flask-sqlalchemy vs sqlalchemy是否有什么好处。 我找不到足够的动机在http://packages.python.org/Flask-SQLAlchemy/index.html或者我不明白的价值! 我希望你的澄清。

Flask-SQLAlchemy的主要function是与Flask应用程序的正确集成 – 它创build和configuration引擎,连接和会话,并configuration它与Flask应用程序一起工作。

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

在理想的世界里,这将是Flask-SQLAlchemy的唯一特征,但实际上它增加了更多的东西。 这里有一个很好的博客文章,其中包括: 揭秘Flask-SQLAlchemy 。

当我第一次使用Flask和SQLAlchemy时,我不喜欢这个开销。 我继续从扩展中提取会话pipe理代码。 这种方法很有效,但是我发现很难做到这一点。

所以更简单的方法(在另一个我正在使用的项目中使用的方法)是放弃Flask-SQLAlchemy ,不要使用它提供的任何附加function。 你将拥有db.session ,你可以像使用纯SQLAlchemy设置一样使用它。

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

Flask-SQLAlchemy […] SQLAlchemy等产品强烈build议将这些产品用作可用的产品。

这个引用和详细的动机你可以在Session FAQ的第二个问题中find。

说实话,我没有看到任何好处。 恕我直言,Flask-SQLAlchemy创build了一个你并不需要的附加层。 在我们的例子中,我们有一个相当复杂的Flask应用程序,它有多个使用ORM和Core的数据库/连接(主 – 从),其中,我们需要控制会话/数据库事务(例如dryrun和commit模式)。 Flask-SQLAlchemy增加了一些额外的function,比如自动销毁会话,假设你有一些东西,这通常不是你所需要的。

正如@schlamar所说,Flask-SqlAlchemy是一个好东西。 我只是想添加一些额外的背景,在那里做的。

不要觉得你正在select一个。 例如,假设我们想要使用Flask-Sqlalchemy模型从表中获取所有logging。 这很简单

 Model.query.all() 

对于很多简单的情况,Flask-Sqlalchemy将会是完全正确的。 我想说的另一点是,如果Flask-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为您提供了一些不错的额外function,您最终还是可以使用SQLAlchemy来实现自己的function。

积极使用Flask-SQLAlchemy


  1. Flask_SQLAlchemy为您处理会话configuration,设置和拆卸。
  2. 为您提供了声明式的基础模型,使查询和分页更容易
  3. 后端特定设置.Flask-SQLAlchemy扫描已安装的库以支持Unicode,如果失败则自动使用SQLAlchemy Unicode。
  4. 有一个名为apply_driver_hacks的方法,它自动将默认值设置为像MySQL pool-size这样的thigs
  5. 在方法create_all()和drop_all()方面有很好的构build,用于创build和删除所有表。 如果你做了一些愚蠢的事情,用于testing和python命令行
  6. 它提供了get_or_404()而不是get()和find_or_404()而不是find()代码示例,位于> http://flask-sqlalchemy.pocoo.org/2.1/queries/

自动设置表名。 Flask-SQLAlchemy自动设置你的表名来转换你的ClassName > class_name这可以通过设置__tablename__ class List项来覆盖

使用Flask-SQLAlchemy的消极方面


  1. 使用Flask-SQLAlchemy会增加额外的困难,从Flask迁移到让金字塔如果你需要。 这主要是由于Flask_SQLAchemy上的自定义声明基础模型。
  2. 使用Flask-SQLAlchemy可能会冒险使用一个比SQLAlchemy本身小得多的社区的包,我不能很快从活跃的开发中退出。
  3. 如果你不知道他们在那里,Flask-SQLAlchemy有一些很好的额外function可以让你感到困惑。

这里是一个利益的例子 – sqlalchemy让你在普通的sqlalchemy。

假设你正在使用flask_user。

flask_user自动创build和authentication用户对象,所以它需要访问你的数据库。 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(not-flask-sqlalchemy),您可能会对将对象保存到数据库的方式做出不同的假设(如表的名称),因此您必须编写自己的适配器类。