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

如何实现SQLite单表三字段拼接后插入另一表?(PyQt5)

实现details表到view表的数据同步与全名拼接

首先得提个小细节:你创建的view表字段名full name带空格,这在SQL操作里很容易触发语法错误,建议改成full_name(如果非要保留空格,后续SQL语句里得用双引号/反引号把字段名包裹起来)。

下面给你两种实用的实现方案,按需选择:

方案一:保存数据时手动同步(适合简单场景)

直接修改你的save_data方法,在把数据插入details表之后,拼接全名并同步到view表:

def save_data(self):
    title = self.title_combo.currentText()
    first_name = self.first_name_line.text()
    last_name = self.last_name_line.text()
    mobile = self.mobile_line.text()
    designation = self.desig_line.text()

    # 先插入details表
    r = self.emp_model.record()
    r.setValue("title", title)
    r.setValue("first_name", first_name)
    r.setValue("last_name", last_name)
    r.setValue("mobile", mobile)
    r.setValue("designation", designation)
    
    if self.emp_model.insertRecord(-1, r):
        self.emp_model.select()
        # 拼接全名,用strip()去掉多余空格(比如title为空时的开头空格)
        full_name = f"{title} {first_name} {last_name}".strip()
        # 同步到view表
        query = QSqlQuery()
        # 这里用修改后的full_name字段,若坚持用full name,改成"full name"
        query.prepare('INSERT INTO view (full_name, mobile, designation) VALUES (?, ?, ?)')
        query.addBindValue(full_name)
        query.addBindValue(mobile)
        query.addBindValue(designation)
        
        if not query.exec_():
            print(f"同步view表失败: {query.lastError().text()}")
        # 更新view表的显示
        self.view_model.select()
    else:
        print(f"插入details表失败: {self.emp_model.lastError().text()}")

别忘了把创建view表的SQL语句同步修改:

query.exec_("CREATE TABLE IF NOT EXISTS view(full_name TEXT, mobile TEXT, designation TEXT)")

方案二:用SQLite触发器自动同步(推荐,更省心)

这种方式不需要在Python代码里维护同步逻辑,直接让数据库自动处理。当details表有插入、更新、删除操作时,view表会自动同步,非常适合需要实时同步的场景。

修改你初始化数据库的代码,添加触发器:

if db.open():
    query = QSqlQuery()
    query.exec_("CREATE TABLE IF NOT EXISTS details(title TEXT, first_name TEXT, last_name TEXT, mobile TEXT, designation TEXT)")
    # 给view表加details_id字段,关联details表的记录,方便后续更新/删除
    query.exec_("CREATE TABLE IF NOT EXISTS view(full_name TEXT, mobile TEXT, designation TEXT, details_id INTEGER)")
    
    # 插入触发器:details新增记录时,自动同步到view
    query.exec_('''
    CREATE TRIGGER IF NOT EXISTS sync_details_insert
    AFTER INSERT ON details
    BEGIN
        INSERT INTO view (full_name, mobile, designation, details_id)
        VALUES (
            TRIM(NEW.title || ' ' || NEW.first_name || ' ' || NEW.last_name),
            NEW.mobile,
            NEW.designation,
            NEW.rowid
        );
    END;
    ''')
    
    # 更新触发器:details记录更新时,自动更新view对应记录
    query.exec_('''
    CREATE TRIGGER IF NOT EXISTS sync_details_update
    AFTER UPDATE ON details
    BEGIN
        UPDATE view
        SET 
            full_name = TRIM(NEW.title || ' ' || NEW.first_name || ' ' || NEW.last_name),
            mobile = NEW.mobile,
            designation = NEW.designation
        WHERE details_id = NEW.rowid;
    END;
    ''')
    
    # 删除触发器:details记录删除时,自动删除view对应记录
    query.exec_('''
    CREATE TRIGGER IF NOT EXISTS sync_details_delete
    AFTER DELETE ON details
    BEGIN
        DELETE FROM view WHERE details_id = OLD.rowid;
    END;
    ''')
    
    # 后续的model初始化代码不变
    self.emp_model = QtSql.QSqlTableModel()
    self.emp_model.setTable("details")
    self.emp_model.select()
    self.details_tableview.setModel(self.emp_model)
    self.view_model = QtSql.QSqlTableModel()
    self.view_model.setTable("view")
    self.view_model.select()
    self.full_tableview.setModel(self.view_model)

这样一来,不管你是通过UI添加数据,还是直接修改数据库文件,view表都会自动保持同步,完全不用在Python代码里额外维护同步逻辑。

几个小优化建议

  • 你的UI里tilteLabel拼写错误,应该是titleLabel,修正后更规范。
  • 拼接全名时用strip()(Python)或者SQL里的TRIM(),避免出现多余的空格(比如用户没选择title的时候)。
  • 如果需要支持更新details表的记录,方案一还得额外处理更新逻辑,而方案二的触发器已经帮你搞定了,这也是推荐方案二的核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:37:40