假设有这样的场景, 某实体在具体条目上, 其属性是不定的, 或者其属性是充分稀疏的:
id | name | attr_0 | attr_1 | attr_2 | … | attr_n |
---|---|---|---|---|---|---|
1 | foo | 1 | abc | 33 | … | any |
这种情况下, 把属性看成是单独的实体, 是一个更好的建模方式:
id | name |
---|---|
1 | foo |
id | entity_id | attr_name | attr_value |
---|---|---|---|
1 | 1 | attr_0 | 1 |
2 | 1 | attr_1 | 33 |
… | … | … | … |
n | 1 | attr_n | any |
这种模型下, ORM 层面我们考虑封装一个对操作更友好的上层操作接口, 比如:
1 | obj = Entity() |
实现上, 就是把对象的方法, 包装成 SQLAlchemy
的 ORM
中的对应的关系操作.
1 | class BaseModel(declarative_base()): |
实现上就两点:
_attributes
关系中, 指定 collection_class
, 于是就可以得到一个像 dict
的属性对象了.association_proxy
从 dict
的属性对象中只抽出我们关心的 value
属性值.
这个场景中, 还可以再进一步, 在 Entity
类上实现 dict
的一些方法, 直接操作其 attributes
属性, association_proxy
就直接返回 Entity
的实例, 这样代码可以变成这样:
1 | entity = Entity(name=u'ABC') |