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

PySide6使用QSqlRelationalTableModel插PostgreSQL行外键为空如何解决

问题根因

你遇到的插入失败问题核心是QSqlRelationalTableModel对关联外键字段的赋值逻辑和普通字段不同:直接通过record.setValue给关联的外键字段传整数值时,模型会将其识别为关联表的显示字段值而非外键存储值,自动丢弃传入的整数导致外键字段为NULL。
此外你当前代码中直接取self.ui.currency.currentIndex()作为currencyid是错误的,该值是下拉框的行序号,不是currency表对应的主键ID。

修正步骤

1. 修正currency下拉框的数值绑定

先在__init__方法中填充下拉框时,将每个选项对应的currency主键ID绑定到下拉框的itemData中,示例代码如下:

# 放在__init__方法中model初始化完成之后
currency_model = QSqlTableModel(self)
currency_model.setTable("currency")
currency_model.select()
for i in range(currency_model.rowCount()):
    cur_id = currency_model.record(i).value("id")
    cur_type = currency_model.record(i).value("type")
    self.ui.currency.addItem(cur_type, cur_id)

2. 重写插入逻辑,改用行插入+逐字段赋值的方式

不要使用insertRecord方法,改为先插入空行再通过setData赋值的方式,适配QSqlRelationalTableModel的关联字段赋值规则,修改后的onadd方法如下:

def onadd(self):
    # 插入新空行
    new_row = self.model.rowCount()
    if not self.model.insertRow(new_row):
        print("插入行失败:", self.model.lastError().text())
        return

    # 逐字段赋值,列号和你model定义的顺序对应即可
    self.model.setData(self.model.index(new_row, 1), self.ui.accname.text())
    # 取下拉框绑定的currency主键ID,不是currentIndex
    self.model.setData(self.model.index(new_row, 2), self.ui.currency.currentData())
    self.model.setData(self.model.index(new_row, 4), self.userid)

    # 提交行修改,匹配你设置的OnRowChange编辑策略
    if not self.model.submitAll():
        print("提交失败:", self.model.lastError().text())
        self.model.revertRow(new_row)
        return

    # 提交成功后刷新模型
    self.model.select()
可选兼容方案

如果一定要保留record的写法,需要在赋值后手动开启外键字段的生成标记:

def onadd(self):
    r = self.model.record()
    r.setGenerated("id",False)
    r.setGenerated("created",False)
    r.setGenerated("closed",False)
    r.setValue("name",self.ui.accname.text())
    r.setValue("currencyid",self.ui.currency.currentData())
    r.setValue("createdby",self.userid)
    # 手动开启两个外键字段的生成标记
    r.setGenerated("currencyid", True)
    r.setGenerated("createdby", True)
    if not self.model.insertRecord(-1,r):
        print("插入失败:", self.model.lastError().text())
        return
    self.model.select()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:48:01