我发现mixin模式对于保持DRY非常方便,但是我遇到了序列问题。注意,我正在使用postgres。
我们使用alembic迁移,我真的希望--autogeneration
使用此序列,但我理解this might not be possible right now。但是,看起来设置没有ORM标识符的序列,如果我想执行降级,则可以防止序列被删除。
通过谷歌搜索,我找到了some explanation on how to properly setup a sequence。基本上:将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'