当前位置: 首页 > article >正文

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 @with_session 实现数据库会话管理。


📘 一、整体功能概述

该模块主要实现以下功能:

功能描述
✅ 添加知识库如果不存在则添加,否则更新信息
✅ 列出所有知识库可设置文件数量过滤条件
✅ 检查知识库是否存在使用不区分大小写的匹配方式
✅ 加载知识库基本信息获取名称、向量库类型、嵌入模型
✅ 删除知识库支持按名称删除
✅ 获取知识库详细信息返回字典格式数据,便于接口返回

此外还提供了一个测试入口函数,用于验证这些数据库操作是否正常工作。


🧠 二、代码结构详解

🔹 第一部分:导入依赖与模块说明

from server.db.models.knowledge_base_model import KnowledgeBaseModel
from server.db.session import with_session
  • KnowledgeBaseModel:SQLAlchemy ORM 定义的知识库表模型
  • with_session:一个装饰器,自动注入 SQLAlchemy 的 session 对象,避免手动打开/关闭数据库连接

🔹 第二部分:核心数据库操作函数

1. add_kb_to_db(session, kb_name, kb_info, vs_type, embed_model)

🎯 功能:
  • 向数据库中添加一个新的知识库
  • 若已存在同名知识库,则更新其信息
📌 参数说明:
  • kb_name: 知识库名称(唯一)
  • kb_info: 知识库简介(用于 AI agent 理解用途)
  • vs_type: 向量库类型(如 FAISS、Chroma)
  • embed_model: 嵌入模型名称(如 text-embedding-ada-002)
🔄 工作流程:
  1. 查询是否有同名知识库(忽略大小写)
  2. 若无,则创建并插入新记录
  3. 若有,则更新 info、向量库类型和嵌入模型字段
✅ 返回值:

始终返回 True,表示执行成功


2. list_kbs_from_db(session, min_file_count: int = -1)

🎯 功能:

列出所有文件数量大于指定值的知识库名称列表

📌 参数说明:
  • min_file_count: 最小文件数,用于筛选活跃的知识库
🔄 工作流程:
  • 查询所有满足条件的 kb_name
  • 将结果从 (kb_name,) 转换为 kb_name 字符串列表
✅ 示例输出:
["test_kb", "math_kb", "law_kb"]

3. kb_exists(session, kb_name)

🎯 功能:

检查某个知识库是否存在于数据库中

📌 参数说明:
  • kb_name: 知识库名称(支持模糊匹配,不区分大小写)
✅ 返回值:

布尔值,True 表示存在,False 表示不存在


4. load_kb_from_db(session, kb_name)

🎯 功能:

加载知识库的基本配置信息(名称、向量库类型、嵌入模型)

📌 参数说明:
  • kb_name: 知识库名称(支持模糊匹配)
✅ 返回值:

元组形式 (kb_name, vs_type, embed_model),如果不存在则返回 (None, None, None)


5. delete_kb_from_db(session, kb_name)

🎯 功能:

根据知识库名称删除对应条目

📌 参数说明:
  • kb_name: 知识库名称(支持模糊匹配)
✅ 返回值:

始终返回 True,表示操作成功(即使未找到要删除的对象)


6. get_kb_detail(session, kb_name)

🎯 功能:

获取知识库的完整信息,包括:

  • 名称
  • 简介
  • 向量库类型
  • 嵌入模型
  • 文件数量
  • 创建时间
✅ 返回值:
  • 存在时返回字典:
    {"kb_name": "test_kb","kb_info": "这是一个用于测试的知识库","vs_type": "FAISS","embed_model": "text-embedding-ada-002","file_count": 0,"create_time": datetime.datetime(...)
    }
    
  • 不存在时返回空字典 {}

🔁 三、装饰器机制:@with_session

@with_session
def add_kb_to_db(session, kb_name, kb_info, vs_type, embed_model):

🧩 作用:

  • 自动为你打开数据库会话(session)
  • 函数执行完毕后自动提交事务或回滚异常
  • 避免手动管理 session,提高代码可维护性

💡 类似于上下文管理器:

with get_db() as session:# 执行数据库操作

📐 四、ORM 模型结构(来自 knowledge_base_model.py)

你使用的 KnowledgeBaseModel 应该是如下结构(简化版):

class KnowledgeBaseModel(Base):__tablename__ = 'knowledge_base'id = Column(Integer, primary_key=True, autoincrement=True)kb_name = Column(String(50), unique=True, comment='知识库名称')kb_info = Column(String(200), comment='知识库简介')vs_type = Column(String(50), comment='向量库类型')embed_model = Column(String(50), comment='嵌入模型名称')file_count = Column(Integer, default=0, comment='文件数量')create_time = Column(DateTime, default=func.now(), comment='创建时间')

🧪 五、测试入口函数(if name == “main”)

这是程序的主入口,用于运行测试流程。

✅ 测试步骤如下:

  1. 添加知识库

    • 使用 add_kb_to_db() 添加一个名为 test_kb 的知识库
  2. 检查是否存在

    • 使用 kb_exists() 判断知识库是否入库成功
  3. 获取详细信息

    • 使用 get_kb_detail() 输出当前知识库的所有字段信息
  4. 加载基本信息

    • 使用 load_kb_from_db() 获取 kb_name, vs_type, embed_model
  5. 列出所有知识库

    • 使用 list_kbs_from_db() 获取当前数据库中所有知识库名称
  6. 删除知识库

    • 使用 delete_kb_from_db() 删除刚添加的知识库
  7. 再次检查是否存在

    • 确认删除是否成功

📋 六、测试流程示意

🧪 开始测试知识库数据库操作函数...
📌 正在添加知识库:test_kb
✅ 添加完成
🔍 知识库 test_kb 是否存在?是
📝 获取知识库 test_kb 的详细信息
🧠 加载知识库信息:test_kb, FAISS, text-embedding-ada-002
📋 当前数据库中的知识库列表:
['test_kb']
🗑️ 正在删除知识库:test_kb
✅ 删除完成
🔍 删除后,知识库 test_kb 是否还存在?否
🎉 所有测试通过!

📦 七、适用场景与扩展建议

✅ 适用场景:

场景描述
🧠 AI 助手后台管理多个知识库,支持文档问答
📄 RAG 架构记录每个知识库的向量库类型与嵌入模型
📈 数据统计统计知识库文件数量、创建时间等
🧩 多任务适配不同知识库使用不同 embedding 模型

🛠️ 推荐扩展方向:

扩展点描述
✅ 增加 hash 校验字段避免重复上传相同文件
✅ 添加文件路径字段file_path TEXT,方便定位实际文件位置
✅ 支持软删除is_deleted BOOLEAN DEFAULT False
✅ 支持异步状态标记status ENUM('pending', 'processing', 'done')
✅ 多线程安全优化提升大规模并发访问效率

📊 八、实战代码部分展示:

#!/usr/bin/env python
# coding=utf-8"""
@author: zgw
@date: 2025/6/7 16:07
@source from: 
"""
from server.db.models.knowledge_base_model import KnowledgeBaseModel
from server.db.session import with_session@with_session
def add_kb_to_db(session, kb_name, kb_info, vs_type, embed_model):# 创建知识库实例kb = session.query(KnowledgeBaseModel).filter(KnowledgeBaseModel.kb_name.ilike(kb_name)).first()if not kb:kb = KnowledgeBaseModel(kb_name=kb_name, kb_info=kb_info, vs_type=vs_type, embed_model=embed_model)session.add(kb)else:  # update kb with new vs_type and embed_modelkb.kb_info = kb_infokb.vs_type = vs_typekb.embed_model = embed_modelreturn True@with_session
def list_kbs_from_db(session, min_file_count: int = -1):kbs = session.query(KnowledgeBaseModel.kb_name).filter(KnowledgeBaseModel.file_count > min_file_count).all()kbs = [kb[0] for kb in kbs]return kbs@with_session
def kb_exists(session, kb_name):kb = session.query(KnowledgeBaseModel).filter(KnowledgeBaseModel.kb_name.ilike(kb_name)).first()status = True if kb else Falsereturn status@with_session
def load_kb_from_db(session, kb_name):kb = session.query(KnowledgeBaseModel).filter(KnowledgeBaseModel.kb_name.ilike(kb_name)).first()if kb:kb_name, vs_type, embed_model = kb.kb_name, kb.vs_type, kb.embed_modelelse:kb_name, vs_type, embed_model = None, None, Nonereturn kb_name, vs_type, embed_model@with_session
def delete_kb_from_db(session, kb_name):kb = session.query(KnowledgeBaseModel).filter(KnowledgeBaseModel.kb_name.ilike(kb_name)).first()if kb:session.delete(kb)return True@with_session
def get_kb_detail(session, kb_name: str) -> dict:kb: KnowledgeBaseModel = session.query(KnowledgeBaseModel).filter(KnowledgeBaseModel.kb_name.ilike(kb_name)).first()if kb:return {"kb_name": kb.kb_name,"kb_info": kb.kb_info,"vs_type": kb.vs_type,"embed_model": kb.embed_model,"file_count": kb.file_count,"create_time": kb.create_time,}else:return {}# ========================
# 测试入口
# ========================if __name__ == "__main__":test_kb_name = "test_kb"test_kb_info = "这是一个用于测试的知识库"test_vs_type = "FAISS"test_embed_model = "text-embedding-ada-002"print("🧪 开始测试知识库数据库操作函数...")# 1. 添加知识库print(f"📌 正在添加知识库:{test_kb_name}")add_kb_to_db(kb_name=test_kb_name,kb_info=test_kb_info,vs_type=test_vs_type,embed_model=test_embed_model)print("✅ 添加完成")# 2. 检查是否存在exists = kb_exists(kb_name=test_kb_name)print(f"🔍 知识库 {test_kb_name} 是否存在?{'是' if exists else '否'}")assert exists is True, "❌ 添加知识库失败"# 3. 获取详细信息print(f"📝 获取知识库 {test_kb_name} 的详细信息")detail = get_kb_detail(test_kb_name)print("Detail:", detail)# 4. 加载基本信息kb_name, vs_type, embed_model = load_kb_from_db(test_kb_name)print(f"🧠 加载知识库信息:{kb_name}, {vs_type}, {embed_model}")assert kb_name == test_kb_name, "❌ 加载知识库名称错误"assert vs_type == test_vs_type, "❌ 向量库类型不一致"assert embed_model == test_embed_model, "❌ 嵌入模型不一致"# 5. 列出所有知识库print("📋 当前数据库中的知识库列表:")all_kbs = list_kbs_from_db(min_file_count=-1)print(all_kbs)assert test_kb_name in all_kbs, "❌ 列表中未找到刚添加的知识库"# 6. 删除知识库print(f"🗑️ 正在删除知识库:{test_kb_name}")delete_kb_from_db(test_kb_name)print("✅ 删除完成")# 7. 再次检查是否存在exists_after_delete = kb_exists(kb_name=test_kb_name)print(f"🔍 删除后,知识库 {test_kb_name} 是否还存在?{'是' if exists_after_delete else '否'}")assert exists_after_delete is False, "❌ 删除失败"print("🎉 所有测试通过!")

相关文章:

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found"​, "n…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...

Kafka入门-生产者

生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

深度学习水论文:mamba+图像增强

🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)&#xff…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 ​…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...