feat: auto table creation (lazy) for ragroleplay

- Refactor create_table() to use per-table schema functions
- Add _TABLE_SCHEMAS dict mapping table names to schema factories
- Add ensure_table() for lazy table creation on first access
- Tables auto-create if missing when any CRUD operation is called
This commit is contained in:
Dita Aji Pratama 2026-07-12 13:36:54 +07:00
parent 414f94811a
commit 11d05a937e

View File

@ -1,10 +1,11 @@
import requests, gc, lancedb, pyarrow, uuid import requests, gc, lancedb, pyarrow, uuid
from datetime import datetime from datetime import datetime
def create_table(db_path, vector_size):
db = lancedb.connect(db_path)
schema_user = pyarrow.schema([ # ─── Table Schemas ────────────────────────────────────────────────────────────
def _schema_user(vector_size):
return pyarrow.schema([
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
pyarrow.field('fullname', pyarrow.string(), metadata={'description': 'Fullname'}), pyarrow.field('fullname', pyarrow.string(), metadata={'description': 'Fullname'}),
@ -16,9 +17,9 @@ def create_table(db_path, vector_size):
pyarrow.field('xampp_username', pyarrow.string(), nullable=True, metadata={'description': 'XAMPP username'}), pyarrow.field('xampp_username', pyarrow.string(), nullable=True, metadata={'description': 'XAMPP username'}),
pyarrow.field('vector_fullname', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of fullname'}), pyarrow.field('vector_fullname', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of fullname'}),
]) ])
db.create_table("knowledge_user", schema=schema_user)
def _schema_memories(vector_size):
schema_memories = pyarrow.schema([ return pyarrow.schema([
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
pyarrow.field('character', pyarrow.string(), metadata={'description': 'Active Character'}), pyarrow.field('character', pyarrow.string(), metadata={'description': 'Active Character'}),
@ -30,9 +31,9 @@ def create_table(db_path, vector_size):
pyarrow.field('emotional', pyarrow.string(), metadata={'description': 'Character emotional state'}), pyarrow.field('emotional', pyarrow.string(), metadata={'description': 'Character emotional state'}),
pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of combined data'}), pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of combined data'}),
]) ])
db.create_table("knowledge_memories", schema=schema_memories)
def _schema_scenario(vector_size):
schema_scenario = pyarrow.schema([ return pyarrow.schema([
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
pyarrow.field('character', pyarrow.string(), metadata={'description': 'Active Character'}), pyarrow.field('character', pyarrow.string(), metadata={'description': 'Active Character'}),
@ -40,9 +41,9 @@ def create_table(db_path, vector_size):
pyarrow.field('scenario', pyarrow.string(), metadata={'description': 'Detailed scenario description'}), pyarrow.field('scenario', pyarrow.string(), metadata={'description': 'Detailed scenario description'}),
pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of scenario'}), pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of scenario'}),
]) ])
db.create_table("knowledge_scenario", schema=schema_scenario)
def _schema_todo(vector_size):
schema_todo = pyarrow.schema([ return pyarrow.schema([
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
pyarrow.field('keyword', pyarrow.string(), metadata={'description': 'Keywords to trigger to-do'}), pyarrow.field('keyword', pyarrow.string(), metadata={'description': 'Keywords to trigger to-do'}),
@ -50,9 +51,9 @@ def create_table(db_path, vector_size):
pyarrow.field('do', pyarrow.string(), metadata={'description': 'Do'}), pyarrow.field('do', pyarrow.string(), metadata={'description': 'Do'}),
pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of keyword+when'}), pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of keyword+when'}),
]) ])
db.create_table("knowledge_todo", schema=schema_todo)
def _schema_outfit_set(vector_size):
schema_outfit_set = pyarrow.schema([ return pyarrow.schema([
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
pyarrow.field('keyword', pyarrow.string(), metadata={'description': 'Keywords of outfit set'}), pyarrow.field('keyword', pyarrow.string(), metadata={'description': 'Keywords of outfit set'}),
@ -60,9 +61,9 @@ def create_table(db_path, vector_size):
pyarrow.field('outfit', pyarrow.string(), metadata={'description': 'Outfit set description'}), pyarrow.field('outfit', pyarrow.string(), metadata={'description': 'Outfit set description'}),
pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of keyword+when'}), pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of keyword+when'}),
]) ])
db.create_table("knowledge_outfit_set", schema=schema_outfit_set)
def _schema_world(vector_size):
schema_world = pyarrow.schema([ return pyarrow.schema([
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
pyarrow.field('category', pyarrow.string(), metadata={'description': 'Category of world'}), pyarrow.field('category', pyarrow.string(), metadata={'description': 'Category of world'}),
@ -70,9 +71,9 @@ def create_table(db_path, vector_size):
pyarrow.field('description', pyarrow.string(), metadata={'description': 'Detailed world description'}), pyarrow.field('description', pyarrow.string(), metadata={'description': 'Detailed world description'}),
pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of combined content'}), pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of combined content'}),
]) ])
db.create_table("knowledge_world", schema=schema_world)
def _schema_object(vector_size):
schema_object = pyarrow.schema([ return pyarrow.schema([
pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}),
pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}),
pyarrow.field('keyword', pyarrow.string(), metadata={'description': 'Keywords of object'}), pyarrow.field('keyword', pyarrow.string(), metadata={'description': 'Keywords of object'}),
@ -84,11 +85,36 @@ def create_table(db_path, vector_size):
pyarrow.field('usage', pyarrow.string(), metadata={'description': 'Object usage'}), pyarrow.field('usage', pyarrow.string(), metadata={'description': 'Object usage'}),
pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of keyword+when'}), pyarrow.field('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of keyword+when'}),
]) ])
db.create_table("knowledge_object", schema=schema_object)
# parameters: eat, drink, sleep
# Time: morning, afternoon, evening, night _TABLE_SCHEMAS = {
'knowledge_user': _schema_user,
'knowledge_memories': _schema_memories,
'knowledge_scenario': _schema_scenario,
'knowledge_todo': _schema_todo,
'knowledge_outfit_set': _schema_outfit_set,
'knowledge_world': _schema_world,
'knowledge_object': _schema_object,
}
# ─── Table Management ─────────────────────────────────────────────────────────
def create_table(db_path, vector_size):
db = lancedb.connect(db_path)
for name, schema_fn in _TABLE_SCHEMAS.items():
db.create_table(name, schema=schema_fn(vector_size))
del db
gc.collect()
def ensure_table(db_path, table_name, vector_size):
db = lancedb.connect(db_path)
existing = db.table_names()
if table_name not in existing:
schema_fn = _TABLE_SCHEMAS.get(table_name)
if schema_fn:
db.create_table(table_name, schema=schema_fn(vector_size))
del db del db
gc.collect() gc.collect()