GLM-Image WebUI教程:生成历史记录持久化存储与SQLite数据库集成

1. 项目背景与需求

GLM-Image是由智谱AI开发的先进文本到图像生成模型,通过Web界面让用户能够轻松生成高质量的AI图像。在日常使用中,用户经常需要回顾之前生成的图像作品,但默认情况下生成记录只是临时保存,关闭应用后就会丢失。

为了解决这个问题,我们需要为GLM-Image WebUI添加生成历史记录的持久化存储功能。通过集成SQLite数据库,我们可以实现:

  • 永久保存每次生成的图像信息
  • 支持按时间、提示词等条件查询历史记录
  • 提供便捷的历史记录管理和查看功能
  • 保持生成结果的可复现性

2. 环境准备与依赖安装

2.1 现有环境检查

首先确认您的GLM-Image WebUI环境已经正常运行:

# 检查Python环境
python --version
# Python 3.8+

# 检查必要的库
pip list | grep -E "gradio|torch|diffusers|sqlite3"

2.2 安装额外依赖

虽然SQLite是Python标准库的一部分,但我们还需要安装一些辅助工具:

# 安装数据库操作相关的库
pip install datasets sqlalchemy

# 安装时间处理库(如果尚未安装)
pip install python-dateutil

3. 数据库设计与实现

3.1 数据库结构设计

我们设计一个简单的SQLite数据库来存储生成历史:

import sqlite3
import json
from datetime import datetime
from pathlib import Path

class GLMImageDatabase:
    def __init__(self, db_path="glm_image_history.db"):
        self.db_path = db_path
        self.init_database()
    
    def init_database(self):
        """初始化数据库表结构"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        # 创建生成历史表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS generation_history (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            prompt TEXT NOT NULL,
            negative_prompt TEXT,
            width INTEGER,
            height INTEGER,
            steps INTEGER,
            guidance_scale REAL,
            seed INTEGER,
            image_path TEXT NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            parameters TEXT  -- 存储额外的参数配置
        )
        ''')
        
        conn.commit()
        conn.close()

3.2 数据库操作类

创建一个完整的数据库操作类来管理所有数据库交互:

class GLMImageDatabase:
    # ... 初始化代码同上 ...
    
    def add_generation_record(self, prompt, negative_prompt, width, height, 
                             steps, guidance_scale, seed, image_path, parameters=None):
        """添加新的生成记录"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        # 将参数转换为JSON字符串存储
        params_json = json.dumps(parameters) if parameters else None
        
        cursor.execute('''
        INSERT INTO generation_history 
        (prompt, negative_prompt, width, height, steps, guidance_scale, seed, image_path, parameters)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        ''', (prompt, negative_prompt, width, height, steps, guidance_scale, seed, image_path, params_json))
        
        conn.commit()
        record_id = cursor.lastrowid
        conn.close()
        
        return record_id
    
    def get_recent_records(self, limit=10):
        """获取最近的生成记录"""
        conn = sqlite3.connect(self.db_path)
        conn.row_factory = sqlite3.Row  # 以字典形式返回结果
        cursor = conn.cursor()
        
        cursor.execute('''
        SELECT * FROM generation_history 
        ORDER BY created_at DESC 
        LIMIT ?
        ''', (limit,))
        
        records = cursor.fetchall()
        conn.close()
        
        # 将参数JSON字符串转换回字典
        for record in records:
            if record['parameters']:
                record['parameters'] = json.loads(record['parameters'])
        
        return records
    
    def search_records(self, keyword=None, start_date=None, end_date=None):
        """根据条件搜索生成记录"""
        conn = sqlite3.connect(self.db_path)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        
        query = "SELECT * FROM generation_history WHERE 1=1"
        params = []
        
        if keyword:
            query += " AND (prompt LIKE ? OR negative_prompt LIKE ?)"
            params.extend([f"%{keyword}%", f"%{keyword}%"])
        
        if start_date:
            query += " AND created_at >= ?"
            params.append(start_date)
        
        if end_date:
            query += " AND created_at <= ?"
            params.append(end_date)
        
        query += " ORDER BY created_at DESC"
        
        cursor.execute(query, params)
        records = cursor.fetchall()
        conn.close()
        
        for record in records:
            if record['parameters']:
                record['parameters'] = json.loads(record['parameters'])
        
        return records

4. WebUI集成与界面扩展

4.1 修改主程序集成数据库

在WebUI主程序中集成数据库功能:

# 在webui.py中添加以下代码
import gradio as gr
from database import GLMImageDatabase

# 初始化数据库
db = GLMImageDatabase()

def generate_image_with_history(prompt, negative_prompt, width, height, 
                              steps, guidance_scale, seed):
    """包装原有的生成函数,添加历史记录功能"""
    
    # 调用原有的图像生成逻辑
    # 这里假设原有生成函数为 generate_image()
    image_path, result_info = generate_image(
        prompt, negative_prompt, width, height, steps, guidance_scale, seed
    )
    
    # 保存生成记录到数据库
    parameters = {
        'width': width,
        'height': height,
        'steps': steps,
        'guidance_scale': guidance_scale,
        'seed': seed
    }
    
    db.add_generation_record(
        prompt, negative_prompt, width, height, 
        steps, guidance_scale, seed, image_path, parameters
    )
    
    return image_path, result_info

4.2 添加历史记录查看界面

创建一个新的Gradio界面来展示生成历史:

def create_history_interface():
    """创建历史记录查看界面"""
    
    def load_history(limit=20):
        records = db.get_recent_records(limit)
        
        history_html = "<div style='max-height: 600px; overflow-y: auto;'>"
        for record in records:
            history_html += f"""
            <div style='border: 1px solid #ddd; padding: 15px; margin: 10px 0; border-radius: 8px;'>
                <div style='display: flex;'>
                    <div style='flex: 1;'>
                        <h4>生成时间: {record['created_at']}</h4>
                        <p><strong>提示词:</strong> {record['prompt'][:100]}...</p>
                        <p><strong>参数:</strong> {record['width']}x{record['height']}, 
                        步数: {record['steps']}, 引导系数: {record['guidance_scale']}</p>
                        <p><strong>种子:</strong> {record['seed']}</p>
                    </div>
                    <div style='width: 150px;'>
                        <img src='file/{record['image_path']}' style='width: 100%; border-radius: 4px;'>
                    </div>
                </div>
            </div>
            """
        history_html += "</div>"
        return history_html
    
    with gr.Blocks(title="GLM-Image 生成历史") as history_interface:
        gr.Markdown("# 🕐 生成历史记录")
        
        with gr.Row():
            limit_slider = gr.Slider(minimum=5, maximum=100, value=20, step=5, 
                                   label="显示记录数量")
            search_keyword = gr.Textbox(label="搜索关键词", placeholder="输入提示词关键词...")
            refresh_btn = gr.Button(" 刷新历史")
        
        history_output = gr.HTML()
        
        # 交互逻辑
        refresh_btn.click(load_history, inputs=[limit_slider], outputs=history_output)
        limit_slider.change(load_history, inputs=[limit_slider], outputs=history_output)
        search_keyword.change(lambda kw: db.search_records(keyword=kw), 
                            inputs=search_keyword, outputs=history_output)
    
    return history_interface

4.3 主界面集成历史功能

将历史记录功能集成到主界面中:

# 修改主界面创建代码
with gr.Blocks(title="GLM-Image WebUI") as demo:
    # ... 原有的界面代码 ...
    
    # 添加历史记录选项卡
    with gr.Tab("📜 生成历史"):
        history_interface = create_history_interface()
    
    # ... 其他代码 ...

5. 高级功能与优化

5.1 批量操作功能

添加批量删除和导出功能:

def add_batch_operations():
    """添加批量操作功能"""
    
    def delete_records(record_ids):
        """批量删除记录"""
        if not record_ids:
            return "请选择要删除的记录"
        
        conn = sqlite3.connect(db.db_path)
        cursor = conn.cursor()
        
        # 构建IN查询的参数占位符
        placeholders = ','.join('?' * len(record_ids))
        cursor.execute(f"DELETE FROM generation_history WHERE id IN ({placeholders})", record_ids)
        
        conn.commit()
        conn.close()
        return f"成功删除 {len(record_ids)} 条记录"
    
    def export_history(format_type="json"):
        """导出历史记录"""
        records = db.get_recent_records(limit=1000)  # 获取所有记录
        
        if format_type == "json":
            export_data = []
            for record in records:
                export_data.append(dict(record))
            return json.dumps(export_data, indent=2, ensure_ascii=False)
        
        elif format_type == "csv":
            # CSV导出逻辑
            pass
        
        return "导出完成"
    
    return delete_records, export_history

5.2 数据库维护功能

添加数据库维护和优化功能:

def maintain_database():
    """数据库维护功能"""
    
    def cleanup_old_records(max_records=1000):
        """清理旧的记录,只保留最新的N条"""
        conn = sqlite3.connect(db.db_path)
        cursor = conn.cursor()
        
        # 获取总记录数
        cursor.execute("SELECT COUNT(*) FROM generation_history")
        total_count = cursor.fetchone()[0]
        
        if total_count > max_records:
            # 删除超出数量的旧记录
            cursor.execute('''
            DELETE FROM generation_history 
            WHERE id NOT IN (
                SELECT id FROM generation_history 
                ORDER BY created_at DESC 
                LIMIT ?
            )
            ''', (max_records,))
            
            deleted_count = total_count - max_records
            conn.commit()
            conn.close()
            return f"清理了 {deleted_count} 条旧记录"
        
        conn.close()
        return "无需清理,记录数量正常"
    
    def optimize_database():
        """优化数据库性能"""
        conn = sqlite3.connect(db.db_path)
        cursor = conn.cursor()
        cursor.execute("VACUUM")
        conn.close()
        return "数据库优化完成"
    
    return cleanup_old_records, optimize_database

6. 完整部署与使用指南

6.1 修改启动脚本

更新启动脚本以包含数据库功能:

#!/bin/bash
# /root/build/start.sh

# 原有的启动代码...

# 添加数据库初始化
echo "初始化GLM-Image生成历史数据库..."
python -c "
from database import GLMImageDatabase
db = GLMImageDatabase()
print(' 数据库初始化完成')
"

# 启动WebUI
python webui.py "$@"

6.2 使用示例

现在您可以在GLM-Image WebUI中使用历史记录功能:

  1. 查看生成历史:点击"生成历史"选项卡,查看所有历史记录
  2. 搜索特定生成:使用搜索框按关键词查找历史记录
  3. 复现生成结果:点击历史记录中的参数,可以快速重新生成相似图像
  4. 管理历史记录:使用批量操作功能管理生成历史

6.3 性能考虑

对于大量生成记录的情况,建议:

  • 定期清理旧记录(保留最近1000条)
  • 对常用查询字段创建索引
  • 考虑图像文件的存储管理
# 添加数据库索引优化查询性能
def add_indexes():
    conn = sqlite3.connect(db.db_path)
    cursor = conn.cursor()
    
    # 为常用查询字段添加索引
    cursor.execute("CREATE INDEX IF NOT EXISTS idx_created_at ON generation_history(created_at)")
    cursor.execute("CREATE INDEX IF NOT EXISTS idx_prompt ON generation_history(prompt)")
    
    conn.commit()
    conn.close()

add_indexes()

7. 总结

通过集成SQLite数据库,我们成功为GLM-Image WebUI添加了生成历史记录的持久化存储功能。这个解决方案提供了:

  • 完整的历史记录管理:保存所有生成参数和结果图像路径
  • 便捷的查询功能:支持按时间、关键词等多种方式查找历史记录
  • 可复现的生成结果:通过保存的种子和参数,可以重新生成相同图像
  • 友好的用户界面:集成到WebUI中,操作简单直观

这个功能大大提升了GLM-Image的使用体验,让用户能够更好地管理和回顾自己的创作成果。您可以根据实际需求进一步扩展这个系统,比如添加用户管理、云端同步等高级功能。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐