Flask SQLAlchemy数据映射器与活动记录模式

我最近开始研究Flask和Flask-SQLAlchemy。 从Django的背景来看,我发现Flask-SQLAlchmey相当复杂。 我读过SQLAlchemy实现Data Mapper模式,而Django ORM基于Active Record Pattern。

下面是一个实现代码库模式以访问数据库的示例代码。

这是S.Lott(271k声誉)评论的另一个链接,他说ORM是数据访问层,它与模型是分开的。

我的问题是这些:

  • 你可以在上面的例子中提供一个实际的用例,或者你可以提供一个Data Mapper模式有用的例子吗? 我读过的每个地方都是数据映射器模式在复杂情况下非常有用,但没有看到示例。
  • 在使用数据映射模式的情况下,是否使用了存储库模式?
  • 数据映射器是否鼓吹在与模型不同的类中编写选择查询?
  • 为什么Question.query.filter_by(text = text).all() db.session.query(Question).filter(Question.text == text).all()使用db.session.query(Question).filter(Question.text == text).all()
  • 这不是DataMapper vs ActiveRecord模式的重复,因为这只是告诉定义,我对实际示例更感兴趣。


    逐点。

    1。

    我有一个遗留数据库,我必须编写一些数据处理实用程序。 使用Mapper模式,不使用ORM / ActiveRecord风格,在编写查询时让我对使用ActiveRecord非常简单。 它运行在类似于SQL子句的很好的可组合对象上,从SQL注入屏蔽掉。

    “被动”对象允许更多的灵活性/一致性:复杂连接的结果是一个命名元组,这是简单选择的结果。 没有关心的身份,没有相同身份的缓存对象。

    所有更新都是明确的; 不是在别处修改某些状态的“保存”,没有在.save()上运行的钩子等。这使得有效的批量更新不重要,如果将正确的数据发送到DB,则不会产生麻烦。 两者都对我有利。 一般情况下,“取决于”。 例如,我必须在插入后手动获取数据库生成的ID。 明确运行此查询是一些额外的工作。 能够在一个查询中做到这一点,而不是每个记录一个查询,对我来说是一个巨大的福音。

    SQLAlchemy具有分层设计,即使您在ORM上层声明事物并正常操作它,也可以访问较低的“映射器”级别。 例如,在Django中,如果/仍然有可能,它并不那么简单。

    2。

    在这个例子中,'储存库'看起来像是在'映射器'之上构建的级别。 该存储库可以建立在普通的DBAPI之上,但映射器使一些事情变得更简单,如更好的参数绑定,结果集的命名元组以及包含可组合的可重用部分的普通SQL之上的包装器。

    该映射器还提供了一定程度的数据库独立性。 例如SQL Server和Postgres有不同的方式来连接字符串; 该映射器提供了一个统一的界面。

    3。

    你在你使用它的地方写下你的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也很重要。

    我通常会在sessionmaker写一个简单的包装器,并写下如下的东西:

    with my_database.transaction() as trans:
       records = trans.query(...)
       ...
       updated = trans.execute(...).rowcount
    # Here the transaction commits if all went well.
    

    当我确定没有DML应该在这个块中运行时,我使用总是回滚的.readonly_transaction()

    在很多情况下,隐式事务很好。 Django允许你使用@transaction.atomic来装饰一个方法,并拥有一个半显式事务控制,在99%的情况下是足够的。 但有时你需要更细的粒度。


    完全同意上面的答案:是的,SQLAlchemy的数据映射器模式更加灵活,对于复杂的查询,它确实更强大,更少魔法和更多控制。

    但是,在诸如CRUD之类的简单任务中,SQLAlchemy的代码变得过重/过度/冗余。

    例如,要在最简单的“创建”控制器中创建一些对象,您需要如下所示:

    user = User(name='Nick', surname='Nickson')
    session.add(user)
    session.flush()
    

    在Active Record ORM中,您只需要单个字符串。

    那么, 对于简单的任务 ,我们中的一些人可能想要更简单的事情。 我的意思是拥有Active Record for SQLAlchemy将会很酷。

    好消息:我最近为此创建了一个包(它也包含其他有用的东西)。

    检查出来:https://github.com/absent1706/sqlalchemy-mixins

    链接地址: http://www.djcxy.com/p/96053.html

    上一篇: Flask SQLAlchemy Data Mapper vs Active Record Pattern

    下一篇: require packages of other modules