默认sqlite 缺少uuid 函数, sqlite-loadable-rs 是一个基于rust包装的框架,可以用来快速开发sqlite 扩展,以下是一个简单测试

项目准备

  • cargo.toml

注意当前edition = "2021" ,2024 因为一些macro的问题,编译会有问题,对于uuid 的生成使用了uuid crate

[package]
name = "uuid"
version = "0.1.0"
edition = "2021"

[dependencies]
sqlite-loadable = "0.0.5"
uuid = {version="1.17.0","features"=["v4"]}
[lib]
crate-type=["lib", "staticlib", "cdylib"]

开发uuid 函数

核心就是提供方法并通过sqlite-loadable-rs 提供的macro 进行暴露

  • lib.rs
use sqlite_loadable::prelude::*;
use uuid::Uuid;

use sqlite_loadable::{api, define_scalar_function, Result};

fn uuid(context: *mut sqlite3_context, _values: &[*mut sqlite3_value]) -> Result<()> {
    api::result_text(context, &Uuid::new_v4().to_string())?;
    Ok(())
}

#[sqlite_entrypoint]
fn sqlite3_uuid_init(db: *mut sqlite3) -> Result<()> {
    let flags = FunctionFlags::UTF8;
    define_scalar_function(db, "uuid", 0, uuid, flags)?;
    Ok(())
}

代码使用

通过python 使用

  • app.py
import sqlite3
import numpy as np
import sqlite_vec
from sqlite_vec import serialize_float32
db = sqlite3.connect("examplev2.db")
db.enable_load_extension(True)
sqlite_vec.load(db)
db.load_extension("./libsqlite_uuid.dylib")
db.enable_load_extension(False)
vector = np.random.rand(2).astype(np.float32)
vector = [1,8]
db.execute('''
CREATE virtual TABLE IF NOT EXISTS vec_documents using vec0 (id INTEGER PRIMARY KEY,embedding FLOAT[2],name text,version text)
''')
# 插入数据
db.execute(
    "INSERT INTO vec_documents (embedding,name,version) VALUES (?,?,uuid())",
    (serialize_float32(vector),"example_name")
)
result = db.execute('''
    select * from vec_documents where embedding=?;
''', (serialize_float32(vector),))

print(result.fetchall())
db.commit()
db.close()
  • 效果

使用sqlite-loadable-rs开发一个简单sqlite uuid 扩展_github

说明

通过sqlite-loadable-rs 对于sqlite 进行扩展是一个挺不错的选择,但是当前对于rust 新版本的支持不是很好

参考资料

https://github.com/asg017/sqlite-base64/blob/main/src/lib.rs

https://github.com/asg017/sqlite-loadable-rs