本地部署Vanna实战,快速解决NLP2SQL

article/2025/8/11 20:42:06

一、背景

​ 随着DeepSeek的火爆,基于AI的应用也如雨后春笋般迸发出来,如何根据用户的一句话来找到用户所需要的信息,采用传统的方式无法通过模糊匹配等实现复杂的业务场景,故探索一种新的思路来实现信息获取。Text2SQL将自然语言文本转换为SQL(结构化查询语言)语句的技术,该技术可以让用户使用自然语言来查询数据库,而无需掌握复杂的SQL语法。

二、Vanna是什么?

​ Vanna的核心是一个Python包,它使用检索增强功能来帮助您使用llm为数据库生成准确的SQL查询。Vanna的工作分为两个简单的步骤——在你的数据上训练一个RAG“模型”,然后问一些问题,这些问题将返回SQL查询,这些查询可以设置为自动在你的数据库上运行。

三、为啥要使用Vanna

​ 起初是通过Dify实现Text2SQL查询,DDL语句放在提示词中,如果DDL比较多,容易造成提示词比较长,输入Token比较多,目前这种方案还处于优化中,目前只是实现此功能。另外一种方案也是想通过Vanna来实现Text2SQL查询。

四、Vanna能力

​ 这个是参考官网的流程图,比较清楚的看出包括两部分在你的数据集上训练RAG模型和问答

4.1 训练RAG模型

​ 把DDL/Schemas描述、文档、参考SQL等交给Vanna训练一个用于RAG检索的“模型”。Vanna的RAG模型训练,支持以下几种方式:

1、DDL语句

​ DDL语句有助于Vanna了解你的数据库表结构信息

vn.train(ddl="CREATE TABLE my_table (id INT, name TEXT)")
2、文档内容

​ 可以是你的企业、应用、数据库相关的任何文档内容,只要有助于Vanna正确生成SQL即可,比如对你行业特有名词的解释、特殊指标的计算方式等。

vn.train(documentation="Our business defines XYZ as ABC")
3、SQL或者SQL问答对

​ 即SQL的样例,这显然有助于大模型学习针对您数据库的知识,特别是有助于理解提出问题的上下文,可以大大提高sql生成正确性。

vn.train(question="What is the average age of our customers?",sql="SELECT AVG(age) FROM customers")
4、训练计划

​ 这是vanna提供的一种针对大型数据库自动训练的简易方法。借助RDBMS本身的数据库内元数据信息来训练RAG model,从而了解到库内的表结构、列名、关系、备注等有用信息。

df_information_schema=vn.run_sql("SELECT * FROM INFORMATION_SCHEMA.COLUMNS")plan=vn.get_training_plan_generic(df_information_schema)
vn.train(plan=plan)

4.2 问答

​ 提出问题,获得回答,RAG模型训练完成后,可以用自然语言直接提问。Vanna会利用RAG与LLM生成SQL,并自动运行后返回结果。

4.3 实践

​ 基于以上初步的了解,本地环境进行部署实践,需要先初始化本地的python env,这里使用anaconnda来初始化,ollama模型部署框架,词向量嵌入模型(放在本地向量数据库的缓存目录),以及数据准备。

五、vanna部署

5.1 大模型环境

这里部赘述了,有需要的看公众号 DataSpeed 历史的文章。此处以千问模型为例

ollama run qwen:7b

5.2 chromaDB本地向量数据库

vanna 默认使用 chromaDB本地向量库,chromaDB默认使用all-MiniLM-L6-v2模型。

5.3 Anaconda本地环境

需要准备一些必要的依赖

conda create -n vanna -y python=3.9
conda activate vanna
pip install 'vanna[chromadb,ollama,mysql]'
pip install ipykernel
  • 若包安装时出现的 chroma-hnswlib 问题,下载vs_tools 并安装如下内容,然后重试安装依赖。

5.4 数据准备

准备一些演示数据

CREATE TABLE IF NOT EXISTS vuser (`id` INT PRIMARY KEY COMMENT '用户ID', username VARCHAR(50) COMMENT '用户名',email VARCHAR(100) COMMENT '电子邮件', age INT COMMENT '年龄',gender VARCHAR(10) COMMENT '性别(男/女)',city VARCHAR(50) COMMENT '城市'
) COMMENT='用户信息表' CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci;INSERT INTO vuser (`id`, username, email, age, gender, city) VALUES
(1, '张三', 'zhangsan@example.com', 30, '男', '北京'),
(2, '李四', 'lisi@example.com', 25, '女', '上海'),
(3, '王五', 'wangwu@example.com', 40, '男', '广州'),
(4, '赵六', 'zhaoliu@example.com', 35, '女', '深圳'),
(5, '小明', 'xiaoming@example.com', 28, '男', '成都'),
(6, '小红', 'xiaohong@example.com', 45, '女', '重庆'),
(7, '小华', 'xiaohua@example.com', 32, '男', '天津'),
(8, '小丽', 'xiaoli@example.com', 27, '女', '南京'),
(9, '小李', 'xiaoli2@example.com', 38, '男', '武汉'),
(10, '小美', 'xiaomei@example.com', 33, '女', '西安');

5.4、Vanna启动部署

python代码demo如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: zhyaoeng
@Project :vannaTest 
@Time    : 2025/3/18 16:27
@File    : testv.py
@Software: PyCharm# code is far away from bugs with the god animal protectingI love animals. They taste delicious.┏┓      ┏┓┏┛┻━━━┛┻┓┃      ☃      ┃┃  ┳┛  ┗┳  ┃┃      ┻      ┃┗━┓      ┏━┛┃      ┗━━━┓┃  神兽保佑    ┣┓┃ 永无BUG!   ┏┛┗┓┓┏━┳┓┏┛┃┫┫  ┃┫┫┗┻┛  ┗┻┛
"""
from vanna.ollama import Ollama
from vanna.chromadb import ChromaDB_VectorStore
from vanna.flask import VannaFlaskAppclass MyVanna(ChromaDB_VectorStore, Ollama):def __init__(self, config=None):ChromaDB_VectorStore.__init__(self, config=config)Ollama.__init__(self, config=config)vn = MyVanna(config={'model': 'qwen:7b','ollama_host': 'http://127.0.0.1:11434'})vn.connect_to_mysql(host='192.168.15.xxx', dbname='las', user='rot', password='1234', port=3306)# The information schema query may need some tweaking depending on your database. This is a good starting point.
df_information_schema = vn.run_sql("SELECT * FROM INFORMATION_SCHEMA.COLUMNS")# This will break up the information schema into bite-sized chunks that can be referenced by the LLM
plan = vn.get_training_plan_generic(df_information_schema)vn.train(ddl="""CREATE TABLE IF NOT EXISTS vuser (`id` INT PRIMARY KEY COMMENT '用户ID',username VARCHAR(50) COMMENT '用户名',email VARCHAR(100) COMMENT '电子邮件',age INT COMMENT '年龄',gender VARCHAR(10) COMMENT '性别(男/女)',city VARCHAR(50) COMMENT '城市'
) COMMENT='用户信息表' CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
""")if __name__ == '__main__':app = VannaFlaskApp(vn)app.run()

5.5 查询结果

​ 执行以上py文件后运行结果如图所示,点击http://localhost:8084进入页面

这里举个例子:
要查询表中年龄最小的用户,就会根据问题转化成对应的SQL,执行查询语句,返回结果,查询的正确结果为李四,如果查询结果正确,可以点击Yes,将此问答结果添加到训练数据中

六、vanai本地化

上面代码只能进行demo验证,日常使用时还是使用本地向量库和大模型,并放在服务器上长期使用和训练。笔者搜了很多本地化的教程,大家都写的很简单,为了助力读者快速上收,我写的详细一些。

这里使用已有的qdrant向量库和ollama大模型。

6.1 添加依赖

pip install fastembed
pip install PyMySQL

6.2 本地化Python案例

from vanna.ollama import Ollama
from vanna.flask import VannaFlaskApp
from vanna.qdrant import Qdrant_VectorStore
from qdrant_client import QdrantClientqdrant_url = 'http://xxx:6333'
ollama_url = 'http://xxx:11434'class MyVanna(Qdrant_VectorStore, Ollama):def __init__(self, config=None):Qdrant_VectorStore.__init__(self, config=config)Ollama.__init__(self, config=config)vn = MyVanna(config={'url':qdrant_url,'https':qdrant_url,'ollama_host': ollama_url,'model': 'deepseek-r1:14b'})vn.connect_to_mysql(host='192.168.15.xxx', dbname='las', user='rot', password='1234', port=3306)# The information schema query may need some tweaking depending on your database. This is a good starting point.
df_information_schema = vn.run_sql("SELECT * FROM INFORMATION_SCHEMA.COLUMNS")# This will break up the information schema into bite-sized chunks that can be referenced by the LLM
plan = vn.get_training_plan_generic(df_information_schema)vn.train(ddl="""CREATE TABLE IF NOT EXISTS vuser (`id` INT PRIMARY KEY COMMENT '用户ID',username VARCHAR(50) COMMENT '用户名',email VARCHAR(100) COMMENT '电子邮件',age INT COMMENT '年龄',gender VARCHAR(10) COMMENT '性别(男/女)',city VARCHAR(50) COMMENT '城市'
) COMMENT='用户信息表' CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
""")if __name__ == '__main__':app = VannaFlaskApp(vn)app.run()

6.3 代码解释

代码关键在于 MyVannaconfig的参数如何写,也是很多教程没说清楚的地方。

class MyVanna(Qdrant_VectorStore, Ollama):def __init__(self, config=None):Qdrant_VectorStore.__init__(self, config=config)Ollama.__init__(self, config=config)vn = MyVanna(config={'url':qdrant_url,'https':qdrant_url,'ollama_host': ollama_url,'model': 'deepseek-r1:14b'})

授人以鱼不如授人以渔,其实关键要看源码,以Qdrant_VectorStore为例,源码中是对config做出了要求,下面是Qdrant_VectorStore.__init__的config关键代码,因此要在config增加url这个key。 其他的向量或大模型可以参照这个方式来解决。

if client is None:self._client = QdrantClient(location=config.get("location", None),url=config.get("url", None),prefer_grpc=config.get("prefer_grpc", False),https=config.get("https", None),api_key=config.get("api_key", None),timeout=config.get("timeout", None),path=config.get("path", None),prefix=config.get("prefix", None),)

七、总结

vanna可以结合自己的数据库以及向量库进行先训练后问答,这一块儿可以参考官网https://vanna.ai/docs/app/,官网还提供了使用 Vanna 构建一个网站应用程序或者一个应用程序接口(API)https://github.com/vanna-ai/vanna-flask,欢迎大家一起探讨学习。


http://www.hkcw.cn/article/SIXMjPnOBc.shtml

相关文章

【MySQL】基础操作

MySQL(二)基础操作 一、数据库操作 1.创建库 2.查看库 3.选中库 4.删除库 二、表操作 1.创建表 1.1[comment 注释]: 1.2,...: 2.查看表 2.1查看所有表 2.2查看表结构 3.删除表 三、记录操作 1.插入记录 1.1全列插入 1.2指定列插入 1.3…

嵌入式硬件篇---蜂鸣器

蜂鸣器是一种常用的电子发声元件,主要分为有源蜂鸣器和无源蜂鸣器两类。它们在结构、工作原理、驱动方式、应用场景等方面存在显著差异。以下是详细介绍: 一、核心定义与结构差异 1. 有源蜂鸣器 定义: “有源” 指内部自带振荡电路&#x…

工程的焊接技术

一、焊接设备与材料 焊接设备:对应不同焊接方法,如焊条电弧焊设备包括电焊机、焊钳、接地夹等。 焊接材料 焊条 分类:按熔渣性质分为碱性焊条(低氢型)和酸性焊条。 选用原则:根据焊接场景选择,…

HackMyVM-Teacher

信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.43.0/24 Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-01 01:02 EDT Nmap scan report for 192.168.43.1 Host is up (0.0084s latency). MAC Address: C6:45:66:05:91:88 (Unknow…

AE矩形工具蒙版找不到椭圆形工具怎么办?

是不是也跟我一样遇到了这个问题 ? 还以为是自己安装的版本有问题。其实并没有。 只需要选择矩形工具,鼠标左键,长按1s即可有其他选项 这样就解决啦

Linux 学习-模拟实现【简易版bash】

1、bash本质 在模拟实现前,先得了解 bash 的本质 bash 也是一个进程,并且是不断运行中的进程 证明:常显示的命令输入提示符就是 bash 不断打印输出的结果 输入指令后,bash 会创建子进程,并进行程序替换 证明&#x…

【Android SDK(adb命令环境)工具安装下载教程】

1、打开下载地址:SDK 平台工具版本说明 | Android Studio | Android Developers 2、下载Android SDK Platform-Tools压缩包,选择路径进行解压 3、复制SDK文件platform-tools保存的路径 4、配置adb环境变量;按下wini,在设置界面搜索”环境…

Redis可视化工具 RDM mac安装使用

第一步:https://pan.baidu.com/s/10vpdhw7YfDD7G4yZCGtqQg?at1673701651004将dmg下载 第二部:点击下载的dmg文件进行安装、mac可能会提示: 无法验证此App不包含恶意软件 解决方法: 打开系统偏好设置>安全性与隐私>通用&am…

Mac 使用 Crossover 加载 Windows Steam 游戏库,实现 Windows/Mac 共享移动硬盘

Mac 使用 Crossover 加载 Windows Steam 游戏库,实现 Windows/Mac 共享移动硬盘 1. 在Crossover上安装Steam2. Steam容器加载移动硬盘3. 配置Steam库 前言:本文介绍了如何在Crossover上安装Steam并加载外接移动硬盘,实现在Window上下载的游戏…

Mac上媲美TortoiseSVN 的Svn的强大客户端 — macSvn

什么是macSvn? 如果你使用过 svn 那肯定听说过 TortoiseSVN, 但是 TortoiseSVN 并不支持在 mac 上使用。而 macSvn 是一款专为macOS设计的SVN(Subversion)客户端,它和TortoiseSVN一样,提供了直观的图形化操作方式.操作非常方便! …

给Android Studio配置本地gradle和maven镜像地址,加快访问速度

Android Studio在创建工程后默认会访问Google自己的官网去下载gradle和maven依赖项,国内访问Google的速度相当慢,如果没有科学上网的话,甚至无法访问。本文记录如何解决这些问题。 配置本地gradle 下载gradle 首先需要去国内的网站下载gra…

Flutter 打包报错:Execution failed for task ‘:flutter_plugin_android_lifecycle的解决办法

本篇文章主要讲解:Flutter 打包报错:Execution failed for task :flutter_plugin_android_lifecycle的解决办法。 日期:2025年2月16日 作者:任聪聪 报错现象: 报文信息: FAILURE:Buildfailedwithexception…

uniapp从入门到精通(全网保姆式教程)~ 别再说你不会开发小程序了

目录 一、介绍 二、环境搭建(hello world) 2.1 下载HBuilderX 2.2 下载微信开发者工具 2.3 创建uniapp项目 2.4 在浏览器运行 2.5 在微信开发者工具运行 2.6 在手机上运行 三、项目基本目录结构 四、开发规范概述 五、全局配置文件&#xff0…

macOS包管理器HomeBrew的安装和使用(适合小白)

Homebrew 是 macOS 上广受欢迎的包管理器,它让安装、更新、卸载和管理开发工具及应用程序变得非常简单,通过HomeBrew,用户可以快速获取最新版本的软件包,而无需手动下载和安装。本文将简单介绍如何在 Mac 上安装 Homebrew 以及如何…

Android 15 适配之16K Page Size :为什么它会是最坑的一个适配点

首先什么是 Page Size ?一般意义上,页面(Page)指的就是 Linux 虚拟内存管理中使用的最小数据单位,页面大小(Page Size)就是虚拟地址空间中的页面大小, Linux 中进程的虚拟地址空间是由固定大小的页面组成。 Page Size 对于虚拟内…

adblock:为AdGuard和uBlock Origin定制的个性化过滤规则

adblock:为AdGuard和uBlock Origin定制的个性化过滤规则 adblock Personal filters and rules for AdGuard/uBlock Origin 项目地址: https://gitcode.com/gh_mirrors/adb/adblock 项目介绍 adblock 项目是一个开源的过滤规则集合,专门为AdGuard…

Xcode16 iOS18 编译问题适配

问题1:ADClient编译报错问题 报错信息 Undefined symbols for architecture arm64:"_OBJC_CLASS_$_ADClient", referenced from:in ViewController.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use …

Mac如何连上Windows共享文件夹

首先保证mac和windows在同一局域网下 接着打开mac的【finder】,点击【Go】->【Connect to Server】 接下来输入 windows的IP,格式如下 smb://ip,然后点击【Connect】 接下来输入账号密码登录即可 由于我们的是任何人都可以访问,所以我选的…

手拆STL

vector v e c t o r vector vector,动态数组。 先来看一下它的一些基本操作及其拆后残渣。 1.a.push_back(x),将 x x x加入动态数组 a a a的末尾。 实现:a[cnt]x 2.a.size(),查询动态数组 a a a中元素的数量。 实现:cn…

CppCon 2014 学习: C++ Test-driven Development

“Elephant in the Room”这个比喻常用来形容那些大家都知道但没人愿意讨论的重大问题。 这段内容讲的是软件质量管理的经典做法和潜在的问题: 经典做法:开发完成后才进行人工测试(manual testing after creation)。隐喻“Cape o…