From 11d05a937e9eab3dc7da8ae01ebc2291ae608214 Mon Sep 17 00:00:00 2001 From: Dita Aji Pratama Date: Sun, 12 Jul 2026 13:36:54 +0700 Subject: [PATCH] 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 --- lib/ragroleplay.py | 76 +++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/lib/ragroleplay.py b/lib/ragroleplay.py index dfcb6b5..a2723ea 100644 --- a/lib/ragroleplay.py +++ b/lib/ragroleplay.py @@ -1,10 +1,11 @@ import requests, gc, lancedb, pyarrow, uuid 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('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), 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('vector_fullname', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of fullname'}), ]) - db.create_table("knowledge_user", schema=schema_user) - - schema_memories = pyarrow.schema([ + +def _schema_memories(vector_size): + return pyarrow.schema([ pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), 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('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of combined data'}), ]) - db.create_table("knowledge_memories", schema=schema_memories) - - schema_scenario = pyarrow.schema([ + +def _schema_scenario(vector_size): + return pyarrow.schema([ pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), 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('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of scenario'}), ]) - db.create_table("knowledge_scenario", schema=schema_scenario) - - schema_todo = pyarrow.schema([ + +def _schema_todo(vector_size): + return pyarrow.schema([ pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), 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('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of keyword+when'}), ]) - db.create_table("knowledge_todo", schema=schema_todo) - - schema_outfit_set = pyarrow.schema([ + +def _schema_outfit_set(vector_size): + return pyarrow.schema([ pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), 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('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) - - schema_world = pyarrow.schema([ + +def _schema_world(vector_size): + return pyarrow.schema([ pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), 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('vector_context', pyarrow.list_(pyarrow.float32(), vector_size), metadata={'description': 'Vector data of combined content'}), ]) - db.create_table("knowledge_world", schema=schema_world) - - schema_object = pyarrow.schema([ + +def _schema_object(vector_size): + return pyarrow.schema([ pyarrow.field('id', pyarrow.uuid(), metadata={'description': 'Unique identifier (UUID)'}), pyarrow.field('timestamp', pyarrow.timestamp('ms'), metadata={'description': 'When record created'}), 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('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 gc.collect()