SQLAlchemy和PostgreSQL的自动递增

9 投票
3 回答
25542 浏览
提问于 2025-04-17 19:14

我创建了一个表,这个表有一个主键和一个序列,但通过调试和后来查看表的设计时发现,序列并没有被应用,只是被创建了。

from sqlalchemy import create_engine, MetaData, Table, Column,Integer,String,Boolean,Sequence
from sqlalchemy.orm import mapper, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import json
class Bookmarks(object):
    pass

#----------------------------------------------------------------------
engine = create_engine('postgresql://iser:p@host/sconf', echo=True)
Base = declarative_base()

class Tramo(Base):
    __tablename__ = 'tramos'
    __mapper_args__ = {'column_prefix':'tramos'}

    id = Column(Integer, Sequence('seq_tramos_id', start=1, increment=1),primary_key=True)
    nombre = Column(String)
    tramo_data = Column(String)
    estado = Column(Boolean,default=True)

    def __init__(self,nombre,tramo_data):
        self.nombre=nombre
        self.tramo_data=tramo_data

    def __repr__(self):
        return '[id:%d][nombre:%s][tramo:%s]' % self.id, self.nombre,self.tramo_data

Session = sessionmaker(bind=engine)
session = Session()

tabla = Tramo.__table__
metadata = Base.metadata
metadata.create_all(engine)

这个表就是这样创建的

CREATE TABLE tramos (
    id INTEGER NOT NULL, 
    nombre VARCHAR, 
    tramo_data VARCHAR, 
    estado BOOLEAN, 
    PRIMARY KEY (id)
)

我本来希望能看到序列的默认下一个值的声明,但结果并没有。

我还使用了 __mapper_args__,但看起来这个设置被忽略了。

我是不是漏掉了什么?

3 个回答

10

我遇到了一个类似的问题,涉及到复合多列主键。SERIAL 这个东西只会隐式地应用于单列主键。不过,这种行为可以通过 autoincrement 这个参数来控制(默认值是 "auto"):

id = Column(Integer, primary_key=True, autoincrement=True)
12

我知道这个话题已经很久了,但我碰巧遇到了同样的问题,找不到其他地方的解决办法。

经过一些尝试,我用以下代码解决了这个问题:

TABLE_ID = Sequence('table_id_seq', start=1000)

class Table(Base):
    __tablename__ = 'table'

    id = Column(Integer, TABLE_ID, primary_key=True, server_default=TABLE_ID.next_value())

这样就创建了一个序列,并将其作为列 id 的默认值,效果和 SQLAlchemy 自动创建时是一样的。

9

你指定了一个带名字的 Sequence() 对象。如果你不指定这个,系统会自动在 id 主键的设置中加上 SERIAL

CREATE TABLE tramos (
    id INTEGER SERIAL NOT NULL, 
    nombre VARCHAR, 
    tramo_data VARCHAR, 
    estado BOOLEAN, 
    PRIMARY KEY (id)
)

只有当这个列不是主键时,才会生成一个 DEFAULT 值。

在插入数据时,SQLAlchemy 会根据需要发出一个 select nextval(..) 的指令来生成下一个值。想了解更多细节,可以查看 PostgreSQL 的文档

撰写回答