我发现 mixin 模式对于保持 DRY 非常方便,但我在序列方面遇到了麻烦。注意,我使用的是 postgres。
我们使用 alembic 迁移,我真的很想--autogeneration
使用这个序列,尽管我知道现在这可能是不可能的。但是,它看起来像在没有 ORM 标识符的情况下设置序列,如果我想执行降级,可以防止序列在以后被删除。
通过谷歌搜索,我找到了一些关于如何正确设置序列的解释。本质上:将 id 及其序列分开。
当前代码看起来有点像这样:
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declared_attr
class AutoIdMixin(object):
"""Generates an synthetic identifier primary key.
"""
# See: http://docs.sqlalchemy.org/en/latest/core/defaults.html#associating-a-sequence-as-the-server-side-default
@declared_attr
def id_seq(cls):
bases = cls.__bases__
Base = bases[0]
sequence_prefix = 'seq'
schema = cls._schema_name
sequence_id = '_'.join((sequence_prefix, schema, cls.__tablename__, 'id'))
sequence = sa.Sequence(sequence_id, 1, 1, metadata=Base.metadata)
return sequence
@declared_attr
def id(cls):
column_id = sa.Column(sa.types.Integer, cls.id_seq.next_value(), primary_key=True)
return column_id
使用上面的代码,我最终得到一个无用的错误:
AttributeError: Neither 'next_value' object nor 'Comparator' object has an attribute '_set_parent_with_dispatch'