我最近开始研究烧瓶和烧瓶的炼金术。从Django的背景来看,我发现Flask SQLAlchmey相当复杂。我读过SQLAlchemy实现了数据映射器模式,而DjangoOrm则基于活动记录模式。在
Here是编写的示例代码,它实现了访问数据库的存储库模式。在
Here是S.Lott(271k声誉)评论的另一个链接,他说ORM是数据访问层,它与模型分离。在
我的问题是:
Question.query.filter_by(text = text).all()
不比
db.session.query(Question).filter(Question.text == text).all()
?在这不是DataMapper vs ActiveRecord pattern的重复,因为这只是说明了定义,我对实际例子更感兴趣。在
一点一点。在
1.
我有一个遗留数据库,我必须为其编写一些数据处理实用程序。使用Mapper模式,不使用ORM/ActiveRecord样式,使编写查询时与ActiveRecord一样简单。它在类似SQL子句的可组合对象上操作,不受SQL注入的影响。在
“被动”的对象允许更大的灵活性/一致性:复杂连接的结果是命名元组,简单的选择也是这样。没有需要关心的标识,也没有具有相同标识的缓存对象。在
所有更新都是显式的;不是在别处更改的某个状态的“保存”,也没有在
.save()
上运行钩子,等等。这使得高效的批处理更新变得微不足道,如果正确的数据被发送到数据库,则不会带来麻烦。对我来说这两个都是好处。一般情况下,“视情况而定”。例如,我必须在插入之后手动获取数据库生成的id。显式地运行这个查询是一项额外的工作。在我的例子中,能够在一个查询而不是每个记录中执行一个查询是一个巨大的好处。在SQLAlchemy有一个分层设计,允许您访问较低的“mapper”级别,即使您在较高的ORM级别上声明内容并对其进行正常操作。例如,在Django中,如果/当仍然可能的话,就不那么简单了。在
2.
在本例中,“repository”看起来像是构建在“mapper”之上的。存储库本可以构建在纯DBAPI之上,但映射器使一些事情变得更简单,比如更好的参数绑定、为结果集命名的元组,以及在普通SQL之上使用可组合、可重用部分的包装器。在
映射器还提供了一定程度的数据库独立性。E、 SQL Server和Postgres有不同的方式连接字符串;映射器提供统一的接口。在
3.
你可以在使用它的地方写你的
select
。如果您有一个在不同上下文中经常重用的select,则可以将其放入一个方法或函数中。大多数选择都有一个用途,都是在现场构建的。在SQLAlchemy设计的一个很好的特性是可以轻松地存储条件和整个
where
子句,并在select/update/delete语句之间重用它们。在4.
Question.query.filter_by(text = text).all()
使用隐式事务。db.session.query(Question).filter(Question.text == text).all()
使用显式事务。在显式的交易可以让你安心使用DML。当您查询一个快速变化的数据库并希望您的几个相关的
select
看到相同的一致状态时,select
s也很重要。在我通常会在
sessionmaker
周围编写一个简单的包装器,并这样写:当我确定不应该在这个块中运行DML时,我使用总是回滚的
.readonly_transaction()
。在在许多情况下,隐式事务是可以的。Django允许您用
@transaction.atomic
修饰方法,并具有半显式事务控制,在99%的情况下足够了。但有时你需要更精细的粒度。在我之所以使用datamapper而不是activerecord的唯一原因是如果您有严重的可伸缩性问题。datamapper鼓励分离域对象和数据库访问逻辑,而activerecords将数据库访问逻辑放在域对象中。例如,当您提升Flask实例时,它将只在需要时连接到数据库,而在Django中,它将始终连接到数据库。
数据映射器将域对象与数据库访问逻辑隔离开来,而存储库模式是域对象和数据映射器之间的一层。它比数据映射器高一级。例如,在数据映射器模式中,您将拥有直接的getter和setter,在repository模式中,您将拥有可能还包含一些复杂业务逻辑的getter和setter。
数据映射器与模型类分离。只有活动记录模式连接同一类中的getter和setter。
我已经使用SQLAlchemy和Django一段时间了,我肯定更喜欢类似Django的查询。对于我自己的项目,我使用Flask+SQLAlchemy而不是Django的可能性几乎为零。在考虑这两个框架时,生产力和社区是两个最具决定性的因素。
完全同意上面的答案:是的,SQLAlchemy的数据映射器模式确实更灵活,对于复杂的查询,它确实更强大、更不神奇、更易于控制。在
但是,在诸如CRUD这样的简单任务中,SQLAlchemy的代码变得过于超重/过度/冗余。在
例如,要在最简单的“创建”控制器中创建某个对象,您需要如下所示:
在活动记录ORM中,您只需要一个字符串。在
好吧,对于简单的任务,我们中的一些人可能想要更简单的东西。 我的意思是拥有SQLAlchemy的活动记录会很酷。在
好消息:我最近为此创建了一个包(它还包含其他有用的东西)。在
看看:https://github.com/absent1706/sqlalchemy-mixins
相关问题 更多 >
编程相关推荐