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

如何利用SQLAlchemy将嵌套服务订单对象插入Oracle数据库?

基于SQLAlchemy的多表关联插入最优方案

一、优先利用关联关系自动处理(推荐)

不用手动拆分操作,借助SQLAlchemy的关联关系+级联配置,可以一次性完成三张表的插入,同时保证事务一致性,代码简洁且不易出错。

1. 确保SQLAlchemy模型的关联关系配置正确

先确认表模型的外键和关联关系定义,重点配置relationship和cascade属性:

from sqlalchemy import Column, Integer, String, ForeignKey, Sequence
from sqlalchemy.orm import relationship, Session
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class ServiceOrder(Base):
    __tablename__ = 'service_order'
    # Oracle序列生成自增主键
    service_order_id = Column(Integer, Sequence('service_order_seq'), primary_key=True)
    order_number = Column(String(50), unique=True)
    # 一对多关联订单项,级联操作包含新增/更新/删除
    service_order_items = relationship(
        "ServiceOrderItem", 
        back_populates="service_order", 
        cascade="all, delete-orphan"
    )

class ServiceOrderItem(Base):
    __tablename__ = 'service_order_item'
    item_id = Column(Integer, Sequence('order_item_seq'), primary_key=True)
    service_order_id = Column(Integer, ForeignKey('service_order.service_order_id'))
    # 一对一关联组件,uselist=False标记一对一,级联新增
    component = relationship(
        "Component", 
        back_populates="service_order_item", 
        uselist=False, 
        cascade="save-update"
    )
    service_order = relationship("ServiceOrder", back_populates="service_order_items")

class Component(Base):
    __tablename__ = 'component'
    component_id = Column(Integer, Sequence('component_seq'), primary_key=True)
    item_id = Column(Integer, ForeignKey('service_order_item.item_id'), unique=True)
    part_number = Column(String(50))
    service_order_item = relationship("ServiceOrderItem", back_populates="component")

2. Pydantic模型转SQLAlchemy实例

将嵌套的Pydantic模型转换为关联的SQLAlchemy对象:

from pydantic import BaseModel
from typing import List

# 示例Pydantic模型
class ComponentModel(BaseModel):
    part_number: str

class ServiceOrderItemModel(BaseModel):
    component: ComponentModel

class ServiceOrderModel(BaseModel):
    order_number: str
    service_order_items: List[ServiceOrderItemModel]

def pydantic_to_sqlalchemy(order_model: ServiceOrderModel) -> ServiceOrder:
    db_order = ServiceOrder(order_number=order_model.order_number)
    # 遍历订单项,关联组件
    for item_model in order_model.service_order_items:
        db_component = Component(part_number=item_model.component.part_number)
        db_item = ServiceOrderItem(component=db_component)
        db_order.service_order_items.append(db_item)
    return db_order

3. 事务内一次性插入

只需将根对象(ServiceOrder)添加到Session,commit时SQLAlchemy会自动按依赖顺序插入三张表,自动填充外键:

def insert_full_order(session: Session, order_model: ServiceOrderModel) -> int:
    try:
        db_order = pydantic_to_sqlalchemy(order_model)
        session.add(db_order)
        session.commit()
        # 直接从对象获取生成的主键ID
        return db_order.service_order_id
    except Exception as e:
        session.rollback()
        raise e

二、拆分操作的场景(特殊需求下)

如果必须分步插入,可通过flush()在事务内提前获取生成的主键,避免数据不一致:

def split_insert_order(session: Session, order_model: ServiceOrderModel) -> int:
    try:
        # 1. 插入服务订单,flush获取自增ID(事务未提交)
        db_order = ServiceOrder(order_number=order_model.order_number)
        session.add(db_order)
        session.flush()
        order_id = db_order.service_order_id

        # 2. 插入订单项,flush获取item_id
        for item_model in order_model.service_order_items:
            db_item = ServiceOrderItem(service_order_id=order_id)
            session.add(db_item)
            session.flush()
            item_id = db_item.item_id

            # 3. 插入组件,用item_id作为外键
            db_component = Component(item_id=item_id, part_number=item_model.component.part_number)
            session.add(db_component)
        
        session.commit()
        return order_id
    except Exception as e:
        session.rollback()
        raise e

关键注意事项

  • 事务一致性:无论哪种方式,都必须在事务内操作,避免部分插入成功的脏数据
  • Oracle序列配置:自增主键需绑定Oracle序列,确保SQLAlchemy能正确获取生成的ID
  • 级联规则:根据业务需求调整cascade参数,避免误删或漏更关联数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:22:39