我有一个带有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
,即使它不是主键?
答案 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