0

我发现 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'
4

1 回答 1

0

在 RTM 时刻,我好像错过了一个关键字:server_default

    @declared_attr
    def id(cls):
        sequence = cls.id_seq
        column_id = sa.Column(sa.types.Integer, server_default=sequence.next_value(), primary_key=True)
        return column_id
于 2017-08-01T03:19:39.400 回答