【问题标题】:How to create postgresql's sequences in Alembic如何在 Alembic 中创建 postgresql 的序列
【发布时间】:2013-06-16 06:46:41
【问题描述】:

我正在使用alembic 来维护我的表格。同时,我使用声明的方式更新我的模型。

这是alembic的一张桌子:

op.create_table(
    'groups',
    Column('id', Integer, Sequence('group_id_seq'), primary_key=True),
    Column('name', Unicode(50)),
    Column('description', Unicode(250)),
)

模型如下:

class Group(Base):
    __tablename__ = 'groups'
    id = Column(Integer, Sequence('group_id_seq'), primary_key=True)
    name = Column(Unicode(50))
    description = Column(Unicode(250))

    def __init__(self, name, description):
        self.description = description
        self.name = name

您可以看到,我在 alembic 迁移和声明性模型中都使用了 Sequence

但我注意到,在使用 PostgreSQL (v9.1) 时,alembic 不会创建任何序列,因此模型无法创建实例,因为它们将使用 nextval(<sequence name>) 子句。

那么,如何创建我的 alembic 迁移,以便在 postgresql 中真正生成序列?

【问题讨论】:

    标签: sqlalchemy alembic


    【解决方案1】:

    只需将以下内容添加到您的模型中:

    field_seq = Sequence('groups_field_seq')
    field = Column(Integer, field_seq, server_default=field_seq.next_value())
    

    并将以下内容添加到您的迁移文件中(在创建表之前):

    from sqlalchemy.schema import Sequence, CreateSequence
    op.execute(CreateSequence(Sequence('groups_field_seq')))
    

    【讨论】:

      【解决方案2】:

      https://bitbucket.org/zzzeek/alembic/issue/60/autogenerate-for-sequences-as-well-as#comment-4100402找到提示

      按照上一个链接中的CreateSequence,我仍然需要跳过几个环节才能使我的迁移在 SQLite 和 PostgreSQL 中工作。目前我有:

      def dialect_supports_sequences():
          return op._proxy.migration_context.dialect.supports_sequences
      
      
      def create_seq(name):
          if dialect_supports_sequences():
             op.execute(CreateSequence(Sequence(name)))
      

      然后在需要时拨打create_seq

      这是最佳做法吗?

      【讨论】:

      • 是的,这是目前唯一的方法。 from sqlalchemy.schema import Sequence, CreateSequence op.execute(CreateSequence(Sequence("some_sequence"))
      • 我无法查看那个 bitbucket URL。
      • 这里也一样。能把相关内容贴在这里吗?
      • op.get_context().dialect.supports_sequences 似乎比使用_proxy 更稳定。
      • 只是一些额外的信息,因为我自己找不到这个。如果要为序列指定起始值,请执行以下操作:op.execute(CreateSequence(Sequence('tablename_id_seq', 1000)))。另外,请注意,序列声明必须放在 before Alembic 版本文件中的表创建语句中。
      【解决方案3】:

      不确定我的问题是否正确,但没有其他人选择回答,这就是我如何完全正常ids:

      蒸馏器:

      op.create_table('event',
          sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
      

      班级:

      class Event(SQLADeclarativeBase):
          __tablename__ = 'event'
          id = Column(Integer, primary_key = True)
      

      【讨论】:

      • 但是你没有使用我提到的Sequence 的东西。我不认为 PostgreSQL 需要它,但它会在使用自动增量时自动创建它。但是,我认为这是一个必须解决的问题,因为 SQLAlchemy 文档“提倡”使用 Sequence 作为在所有引擎中拥有自动递增 id 的万无一失的方法......
      • 我知道我没有使用它。我没有看到使用它的好处,尤其是当它不起作用时。我检查了您的代码,没有看到任何“从 100 开始序列”或“仅使用偶数”的特殊内容,所以我认为默认行为应该就可以了。有时,其他人说显而易见的事情是帮助我重回正轨的原因。
      • 不适用于 MySQL 的 postgres 或其他任何东西:autoincrement – set the AUTO_INCREMENT flag of the column; currently understood by the MySQL dialect. - alembic.readthedocs.io/en/latest/…
      • @zzzeek 用以下“你所指的答案完全错误”来描述这个答案。
      • @MarcoSulla 的链接已损坏。这是该页面的存档版本:web.archive.org/web/20160611064121/http://…
      【解决方案4】:

      我最近遇到了同样的问题,这就是我解决它的方法。

      op.execute("create sequence SEQUENCE_NAME")
      

      我在升级函数中运行了上述命令,对于降级,分别在降级函数中运行以下代码。

      op.execute("drop sequence SEQUENCE_NAME")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-20
        • 1970-01-01
        • 2012-03-20
        • 2014-07-30
        • 1970-01-01
        • 2014-10-22
        • 2022-07-02
        • 1970-01-01
        相关资源
        最近更新 更多