Skip to content

Commit 5331862

Browse files
authored
Expose ProllyTree SQL API to Python and Add Chronological LangGraph TA-RAG Example (#87)
* Expose ProllyTree SQL API to Python Summary This PR adds complete SQL functionality to the ProllyTree Python bindings, allowing users to execute SQL queries on the versioned key-value store through a new ProllySQLStore class. Changes Core Implementation - Added ProllySQLStore Python class (src/python.rs) - Full SQL query execution via GlueSQL - Multiple output formats: dict, tuples, JSON, CSV - Helper methods for common operations (create_table, insert, select) - Transaction support with commit functionality Python Module Updates - Updated python/prollytree/__init__.py - Conditionally exports ProllySQLStore when SQL feature is available - Graceful fallback when SQL support is not compiled Build System Enhancements - Enhanced python/build_python.sh - Added --with-sql flag to build with SQL support - Added --all-features flag for complete feature set - Added --help documentation - Automatic SQL functionality testing when built with SQL feature - Updated pyproject.toml - Added SQL feature to default maturin build configuration - Allows override via command-line flags Storage Layer - Added current_commit() method (src/git/versioned_store.rs) - Enables retrieving the current HEAD commit ID - Required for SQL commit operations Documentation & Examples - Created comprehensive SQL example (python/examples/sql_example.py) - Demonstrates table creation, data insertion, and querying - Shows all output formats (dict, tuples, JSON, CSV) - Examples of JOINs, GROUP BY, subqueries - UPDATE and DELETE operations - Added SQL test suite (python/tests/test_sql.py) - Tests for all SQL operations - Output format validation - Complex query testing - Static method testing API Usage from prollytree import ProllySQLStore # Initialize store (requires git repository) store = ProllySQLStore(path) # Create table store.create_table("users", [("id", "INTEGER"), ("name", "TEXT")]) # Insert data store.insert("users", [[1, "Alice"], [2, "Bob"]]) # Query with different formats results = store.execute("SELECT * FROM users") # Returns list of dicts labels, rows = store.execute("SELECT * FROM users", format="tuples") json_str = store.execute("SELECT * FROM users", format="json") csv_str = store.execute("SELECT * FROM users", format="csv") # Helper methods store.select("users", columns=["name"], where_clause="id > 1") # Execute multiple queries store.execute_many([query1, query2, query3]) # Commit changes store.commit("Added user data") Building with SQL Support # Build with SQL support ./python/build_python.sh --with-sql # Build and install ./python/build_python.sh --with-sql --install # Run example python3 python/examples/sql_example.py Testing - ✅ All SQL operations tested and working - ✅ Example script runs successfully - ✅ Multiple output formats validated - ✅ Complex queries (JOIN, GROUP BY) functional Breaking Changes None - SQL support is optional and doesn't affect existing functionality. Notes - SQL functionality requires git repository initialization - Based on GlueSQL, some SQL features may have limitations (e.g., no DISTINCT support) - Performance is optimized for versioned operations rather than pure SQL speed * add sql example to run script * rename langgraph example * add langgraph_chronological.py * add loop * add more profiles to the example * remove unused codes * improve run_example.sh
1 parent fea792b commit 5331862

10 files changed

Lines changed: 2394 additions & 17 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Repository = "https://github.com/zhangfengcdt/prollytree.git"
3939
"Bug Tracker" = "https://github.com/zhangfengcdt/prollytree/issues"
4040

4141
[tool.maturin]
42-
features = ["python"]
42+
# Default features - can be overridden with --features flag
43+
features = ["python", "sql"]
4344
module-name = "prollytree"
4445
python-source = "python"

python/build_python.sh

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,38 @@
1313
# limitations under the License.
1414

1515
# Build script for ProllyTree Python bindings
16+
#
17+
# Usage:
18+
# ./build_python.sh # Build with default Python bindings
19+
# ./build_python.sh --with-sql # Build with SQL support
20+
# ./build_python.sh --all-features # Build with all features (Python + SQL)
21+
# ./build_python.sh --features "python sql" # Specify features explicitly
22+
# ./build_python.sh --install # Build and install the package
23+
# ./build_python.sh --with-sql --install # Build with SQL and install
1624

1725
set -e
1826

27+
# Show help if requested
28+
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
29+
echo "Build script for ProllyTree Python bindings"
30+
echo ""
31+
echo "Usage:"
32+
echo " ./build_python.sh [OPTIONS]"
33+
echo ""
34+
echo "Options:"
35+
echo " --with-sql Build with SQL support"
36+
echo " --all-features Build with all features (Python + SQL)"
37+
echo " --features FEATURES Specify features explicitly (e.g., 'python sql')"
38+
echo " --install Install the built package after building"
39+
echo " --help, -h Show this help message"
40+
echo ""
41+
echo "Examples:"
42+
echo " ./build_python.sh # Basic Python bindings"
43+
echo " ./build_python.sh --with-sql # With SQL support"
44+
echo " ./build_python.sh --with-sql --install # Build and install with SQL"
45+
exit 0
46+
fi
47+
1948
echo "🔧 Building ProllyTree Python bindings..."
2049

2150
# Check if maturin is installed
@@ -27,9 +56,33 @@ fi
2756
# Change to project root directory
2857
cd "$(dirname "$0")/.."
2958

59+
# Parse command line arguments for features
60+
FEATURES="python"
61+
for arg in "$@"; do
62+
case $arg in
63+
--features)
64+
shift
65+
FEATURES="$1"
66+
shift
67+
;;
68+
--features=*)
69+
FEATURES="${arg#*=}"
70+
shift
71+
;;
72+
--with-sql)
73+
FEATURES="python sql"
74+
shift
75+
;;
76+
--all-features)
77+
FEATURES="python sql"
78+
shift
79+
;;
80+
esac
81+
done
82+
3083
# Build the wheel
31-
echo "🍹 Building wheel with maturin..."
32-
maturin build --release --features python
84+
echo "🍹 Building wheel with maturin (features: $FEATURES)..."
85+
maturin build --release --features "$FEATURES"
3386

3487
# Find the built wheel
3588
WHEEL_PATH=$(find target/wheels -name "prollytree-*.whl" | head -1)
@@ -54,17 +107,51 @@ from prollytree import ProllyTree, TreeConfig
54107
tree = ProllyTree()
55108
tree.insert(b'test', b'value')
56109
result = tree.find(b'test')
57-
print(f'✅ Test passed: {result == b\"value\"}')
110+
print(f'✅ Basic test passed: {result == b\"value\"}')
58111
"
112+
113+
# Test SQL functionality if available
114+
if [[ "$FEATURES" == *"sql"* ]]; then
115+
echo "🧪 Testing SQL functionality..."
116+
python3 -c "
117+
import tempfile
118+
import subprocess
119+
import os
120+
from prollytree import ProllySQLStore
121+
122+
# Create temp dir and init git
123+
with tempfile.TemporaryDirectory() as tmpdir:
124+
subprocess.run(['git', 'init'], cwd=tmpdir, capture_output=True)
125+
subprocess.run(['git', 'config', 'user.name', 'Test'], cwd=tmpdir, capture_output=True)
126+
subprocess.run(['git', 'config', 'user.email', 'test@test.com'], cwd=tmpdir, capture_output=True)
127+
128+
# Create SQL store
129+
store_dir = os.path.join(tmpdir, 'data')
130+
os.makedirs(store_dir)
131+
store = ProllySQLStore(store_dir)
132+
133+
# Test basic SQL operations
134+
store.create_table('test', [('id', 'INTEGER'), ('name', 'TEXT')])
135+
store.insert('test', [[1, 'Test']])
136+
result = store.select('test')
137+
138+
print(f'✅ SQL test passed: {len(result) == 1 and result[0][\"name\"] == \"Test\"}')
139+
" || echo "⚠️ SQL test skipped (import failed - may need git in temp dir)"
140+
fi
59141
fi
60142

61143
echo "🎉 Build complete!"
62144
echo ""
145+
echo "Built with features: $FEATURES"
146+
echo ""
63147
echo "To install the wheel manually:"
64148
echo " pip install $WHEEL_PATH"
65149
echo ""
66150
echo "To test the bindings:"
67151
echo " python3 test_python_binding.py"
152+
if [[ "$FEATURES" == *"sql"* ]]; then
153+
echo " python3 python/examples/sql_example.py # Test SQL functionality"
154+
fi
68155
echo ""
69156
echo "To publish to PyPI:"
70157
echo " cd python && ./publish_python.sh test # Publish to TestPyPI first"

0 commit comments

Comments
 (0)