整数字段不在SQLAlchemy中自动增量

时间:2016-03-09 16:31:06

标签: python postgresql sqlalchemy flask-sqlalchemy

我有一个带有Integer字段的Flask-SQLAlchemy模型,我想自动增量。它不是主键;它是一个代理ID。该模型看起来像:

class StreetSegment(db.Model):
    id = db.Column(db.Integer, autoincrement=True)
    seg_id = db.Column(db.Integer, primary_key=True)

当我在Postgres数据库中创建表时,id字段将创建为普通整数。如果我插入行而未指定id的值,则不会填充它。有没有什么方法可以强制SQLAlchemy使用SERIAL,即使它不是主键?

2 个答案:

答案 0 :(得分:2)

使用Sequence代替autoincrement

id = db.Column(db.Integer, db.Sequence("seq_street_segment_id"))

答案 1 :(得分:0)

SQLAlchemy does not 支持 auto_increment 用于非主键列。

如果您的数据库支持它,您可以使用序列设置相同的行为。 PostgreSQL 支持这一点。序列实际上并不绑定到非常特定的列。相反,它们存在于数据库级别并且可以重用。序列是确切的构造,SQLAlchemy 用于自动递增主键列。

要使用已接受答案中描述的序列,它必须存在。下面,我有一个使用 SQLAlchemy 进行 alembic 迁移的示例来实现这一点。

您可以将序列与 column constructor 中的列相关联。 DDL Expression Constructs API 可帮助您创建和删除序列。

示例:

from alembic import op
import sqlalchemy as sa

measurement_id_seq = sa.Sequence('Measurement_MeasurementId_seq') # represents the sequence


def upgrade():
  op.execute(sa.schema.CreateSequence(measurement_id_seq)) # create the sequence
  op.create_table(
      'Measurement',
      sa.Column('DataSourceId',
                sa.Integer,
                sa.ForeignKey('DataSource.DataSourceId'),
                nullable=False),
      sa.Column('LocationId',
                sa.Integer,
                sa.ForeignKey('Location.LocationId'),
                nullable=False),
      sa.Column('MeasurementId',
                sa.Integer,
                measurement_id_seq, # the sequence as SchemaItem
                server_default=measurement_id_seq.next_value())) # next value of the sequence as default
      [...]
  op.create_primary_key('Measurement_pkey', 'Measurement',
                        ['DataSourceId', 'LocationId', 'Timestamp'])
  pass


def downgrade():
  op.execute(
      sa.schema.DropSequence(sa.Sequence('Measurement_MeasurementId_seq')))
  op.drop_constraint('Measurement_pkey', 'Measurement')
  op.drop_table('Measurement')
  pass