我应该创build映射器对象还是在SQLAlchemy中使用声明性语法?

有两个(三个,但我不算Elixir ,因为它不是“官方”)用SQLAlchemy定义一个持久对象的方法:

映射器对象的显式语法

from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey from sqlalchemy.orm import mapper metadata = MetaData() users_table = Table('users', metadata, Column('id', Integer, primary_key=True), Column('name', String), ) class User(object): def __init__(self, name): self.name = name def __repr__(self): return "<User('%s')>" % (self.name) mapper(User, users_table) # &lt;Mapper at 0x...; User&gt; 

声明语法

 from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) def __init__(self, name): self.name = name def __repr__(self): return "<User('%s')>" % (self.name) 

我可以看到,在使用映射器对象时,我将ORM定义与业务逻辑完全分开,而在使用声明性语法时,无论何时修改业务逻辑类,我都可以在其中编辑数据库类(理想情况下应该编辑)。

我并不完全确定,哪种方法更适合商业应用?

我无法find这两种映射方法之间的比较,以便能够决定哪个更适合我的项目。

我倾向于使用“正常”的方式(即不是声明性的扩展),因为它允许我“隐藏”,并且避开业务视图中的所有ORM逻辑,但是我想听到两个引人注目的论点方法。

“我不完全确定,哪种方法更适合商业应用?”

一般不能回答。

但是,请考虑这一点。

Django的ORM是严格声明的 – 人们也是如此。

SQLAlchemy做了几件事情,并不是所有的事情都与所有问题有关。

  1. SQLAlchemy从通用Python创build特定于数据库的SQL。 如果您想要混淆SQL,或将Python类映射到现有表,那么您必须使用显式映射,因为您的焦点在SQL上,而不是业务对象和ORM。

  2. SQLAlchemy可以使用声明式的风格(如Django)来为你创build一切。 如果你想这样做,那么你明确地放弃了写表定义,并明确地搞乱了SQL。

  3. Elixir是一个替代scheme,可以让您不必再去查看SQL。

根本的问题是“你想看到并触摸SQL?”

如果你认为触摸SQL使事情更“可维护”,那么你必须使用显式映射。

如果你认为隐藏SQL使事情更“可维护”,那么你必须使用声明式的风格。

  • 如果您认为Elixir可能会与SQLAlchemy发生冲突,或者无法以某种方式履行承诺,那么请不要使用它。

  • 如果你认为药剂师会帮助你,那就使用它。

在我们的团队中,我们确定了声明性语法。

理由:

  • metadata是微不足道的,如果需要的话: User.metadata
  • 你的User类,由于subclassing Base ,有一个很好的ctor,为所有的字段带kwargs。 有用的testing和其他。 例如: user=User(name='doe', password='42') 。 所以不需要写一个ctor!
  • 如果你添加一个属性/列,你只需要做一次。 “不要重复自己”是一个很好的原则。

关于“从业务视图中剔除ORM”:实际上,当“ mapper函数与之匹配时,用“正常”方式定义的User类会被SA严重修改。 恕我直言,声明的方式是更诚实的,因为它尖叫:“这个类在ORM的情况下使用,可能不会像对待你简单的非ORM对象一样对待”。

我发现,如果使用sqlalchemy-migrate来对数据库模式进行版本化(从我的angular度来看,这是一个业务应用程序必备),那么使用映射器对象比声明性语法简单得多。 如果您使用的是mapper对象,只需将表格声明复制/粘贴到迁移版本,然后使用简单的api来修改数据库中的表格。 声明式语法使得这一点变得更加困难,因为在将类复制到迁移版本后,必须从类定义中过滤掉所有的帮助函数。

而且,在我看来,表格之间的复杂关系用映射器对象语法expression得更清楚,但这可能是主观的。