You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI/SQLModel继承Base类时如何将id列设为表首列

问题:SQLModel生成Postgres表时,如何让主键id成为第一列?

现有schemas.py代码如下:

from typing import Optional
from datetime import date
from sqlmodel import SQLModel, Field

class EimBase(SQLModel):
    fimno: Optional[str]
    spv_component_id: Optional[int] 
    eim_technology_name: Optional[str]
    eim_technology_version: Optional[str]
    obsolete_start_date: Optional[date]
    actual_remediation_date: Optional[date]
    intended_remediation_date: Optional[date]
    issuestatus: Optional[str]
    current_manu_phase: Optional[str]
    current_manu_phase_start: Optional[date]
    current_manu_phase_end: Optional[date]
    remediation_type: Optional[str]
    issue_component_id: Optional[str]
    middleware_instance_name: Optional[str]

class Eim(EimBase, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    spv_component_id: Optional[int] = Field(default=None, index=True)

Postgres生成的建表SQL如下,可见id列位于最后:

CREATE TABLE stage_eim (
        fimno VARCHAR,
        spv_component_id INTEGER,
        eim_technology_name VARCHAR,
        eim_technology_version VARCHAR,
        obsolete_start_date DATE,
        actual_remediation_date DATE,
        intended_remediation_date DATE,
        issuestatus VARCHAR,
        current_manu_phase VARCHAR,
        current_manu_phase_start DATE,
        current_manu_phase_end DATE,
        remediation_type VARCHAR,
        issue_component_id VARCHAR,
        middleware_instance_name VARCHAR,
        id SERIAL NOT NULL,
        PRIMARY KEY (id)
)

需求是让id列为表的第一列,但直接将Eim类定义在EimBase之上会触发spv_component_id相关报错,如何在保留现有Schema结构的前提下实现?


解决方案

可以通过新增一个仅包含主键id的基类,让Eim优先继承该基类,再继承原有的EimBase,这样就能让id列排在最前面,同时保留原有结构且避免报错。

修改后的代码如下:

from typing import Optional
from datetime import date
from sqlmodel import SQLModel, Field

# 新增仅包含主键的基类
class EimIdBase(SQLModel):
    id: Optional[int] = Field(default=None, primary_key=True)

class EimBase(SQLModel):
    fimno: Optional[str]
    spv_component_id: Optional[int] 
    eim_technology_name: Optional[str]
    eim_technology_version: Optional[str]
    obsolete_start_date: Optional[date]
    actual_remediation_date: Optional[date]
    intended_remediation_date: Optional[date]
    issuestatus: Optional[str]
    current_manu_phase: Optional[str]
    current_manu_phase_start: Optional[date]
    current_manu_phase_end: Optional[date]
    remediation_type: Optional[str]
    issue_component_id: Optional[str]
    middleware_instance_name: Optional[str]

# 先继承EimIdBase,再继承EimBase
class Eim(EimIdBase, EimBase, table=True):
    spv_component_id: Optional[int] = Field(default=None, index=True)

修改后生成的建表SQL中,id列会成为第一列:

CREATE TABLE stage_eim (
        id SERIAL NOT NULL,
        fimno VARCHAR,
        spv_component_id INTEGER,
        eim_technology_name VARCHAR,
        eim_technology_version VARCHAR,
        obsolete_start_date DATE,
        actual_remediation_date DATE,
        intended_remediation_date DATE,
        issuestatus VARCHAR,
        current_manu_phase VARCHAR,
        current_manu_phase_start DATE,
        current_manu_phase_end DATE,
        remediation_type VARCHAR,
        issue_component_id VARCHAR,
        middleware_instance_name VARCHAR,
        PRIMARY KEY (id)
)

原理说明

SQLModel会按照继承顺序排列字段:先处理第一个父类的字段,再依次处理后续父类的字段,最后处理子类自身定义的字段。通过让Eim先继承包含id的基类,就能让主键列排在所有业务字段之前,同时子类中重写的spv_component_id会覆盖父类的定义,保留索引配置且不会引发报错。


内容的提问来源于stack exchange,提问作者moth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:25:30