Crates.io | yamlbase |
lib.rs | yamlbase |
version | 0.7.2 |
created_at | 2025-06-11 20:30:36.025631+00 |
updated_at | 2025-08-19 12:09:20.102078+00 |
description | A lightweight SQL server that serves YAML-defined tables over standard SQL protocols |
homepage | https://github.com/rvben/yamlbase |
repository | https://github.com/rvben/yamlbase |
max_upload_size | |
id | 1709084 |
size | 1,864,972 |
Yamlbase is a lightweight SQL server designed for local development and testing. Define your database schema and data in simple YAML files and serve them over standard PostgreSQL or MySQL wire protocols.
cargo install yamlbase
git clone https://github.com/rvben/yamlbase
cd yamlbase
cargo install --path .
docker run -p 5432:5432 -v $(pwd)/database.yaml:/data/database.yaml ghcr.io/rvben/yamlbase
database:
name: "test_db"
tables:
users:
columns:
id: "INTEGER PRIMARY KEY"
name: "VARCHAR(100) NOT NULL"
email: "VARCHAR(255) UNIQUE"
created_at: "TIMESTAMP DEFAULT CURRENT_TIMESTAMP"
is_active: "BOOLEAN DEFAULT true"
data:
- id: 1
name: "John Doe"
email: "john@example.com"
created_at: "2024-01-15 10:30:00"
is_active: true
- id: 2
name: "Jane Smith"
email: "jane@example.com"
created_at: "2024-01-16 14:22:00"
is_active: false
# PostgreSQL protocol (default)
yamlbase -f database.yaml
# MySQL protocol
yamlbase -f database.yaml --protocol mysql
PostgreSQL:
# Using psql
psql -h localhost -p 5432 -U admin -d test_db
# Password: password (default)
MySQL:
# Using mysql client
mysql -h 127.0.0.1 -P 3306 -u admin -ppassword test_db
SELECT * FROM users WHERE is_active = true;
SELECT name, email FROM users ORDER BY created_at DESC LIMIT 5;
yamlbase [OPTIONS]
Options:
-f, --file <FILE> Path to YAML database file
-p, --port <PORT> Port to listen on (default: 5432 for postgres, 3306 for mysql)
--bind-address <ADDR> Address to bind to [default: 0.0.0.0]
--protocol <PROTOCOL> SQL protocol: postgres, mysql, sqlserver [default: postgres]
-u, --username <USER> Authentication username [default: admin]
-P, --password <PASS> Authentication password [default: password]
--hot-reload Enable hot-reloading of YAML file changes
-v, --verbose Enable verbose logging
--log-level <LEVEL> Set log level: debug, info, warn, error [default: info]
-h, --help Print help
You can specify authentication credentials directly in the YAML file:
database:
name: "my_db"
auth:
username: "dbuser"
password: "dbpassword"
tables:
# ... your tables
When auth is specified in the YAML file, it overrides command-line arguments. This is useful for:
Different credentials per database file
Keeping credentials with the test data
Simplifying connection strings
INTEGER
/ INT
/ BIGINT
/ SMALLINT
VARCHAR(n)
- Variable-length string with max lengthTEXT
- Unlimited textTIMESTAMP
/ DATETIME
DATE
TIME
BOOLEAN
/ BOOL
DECIMAL(p,s)
/ NUMERIC(p,s)
- Fixed-point decimalFLOAT
/ REAL
DOUBLE
UUID
JSON
/ JSONB
PRIMARY KEY
- Unique identifier for the tableNOT NULL
- Column cannot contain NULL valuesUNIQUE
- All values must be uniqueDEFAULT <value>
- Default value for new rowsREFERENCES table(column)
- Foreign key referenceCURRENT_TIMESTAMP
- Current date and timetrue
/ false
- Boolean valuesSELECT
queries with column selectionWHERE
clauses with comparison operators (=
, !=
, <
, >
, <=
, >=
)AND
/ OR
logical operatorsORDER BY
with ASC
/ DESC
LIMIT
for result paginationSELECT *
)LEFT JOIN
with proper NULL handlingCROSS JOIN
for Cartesian productsROW_NUMBER()
- Sequential row numberingRANK()
- Ranking with tiesPARTITION BY
clause for groupingWITH
clauseCROSS JOIN
operationsUNION ALL
with CTE resultsDISTINCT
and DISTINCT ON
(PostgreSQL-specific):
DISTINCT
for unique rowsDISTINCT ON
for keeping first row per unique column combinationDISTINCT ON
including EXTRACT
and comparisons-- Select with conditions
SELECT * FROM users WHERE is_active = true AND age > 25;
-- Order and limit
SELECT name, email FROM users ORDER BY created_at DESC LIMIT 10;
-- Join tables
SELECT u.name, o.total_amount
FROM users u, orders o
WHERE u.id = o.user_id;
-- LEFT JOIN
SELECT u.name, o.order_id
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
-- Window functions
SELECT name,
ROW_NUMBER() OVER (ORDER BY created_at) as row_num,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as dept_rank
FROM users;
-- Common Table Expressions (CTEs)
WITH active_users AS (
SELECT * FROM users WHERE is_active = true
),
user_orders AS (
SELECT u.*, o.total_amount
FROM active_users u
INNER JOIN orders o ON u.id = o.user_id
)
SELECT * FROM user_orders WHERE total_amount > 100;
-- CTE with CROSS JOIN for date range filtering
WITH DateRange AS (
SELECT '2025-01-01' AS start_date, '2025-01-31' AS end_date
),
FilteredOrders AS (
SELECT o.*
FROM orders o
CROSS JOIN DateRange d
WHERE o.order_date BETWEEN d.start_date AND d.end_date
)
SELECT COUNT(*) FROM FilteredOrders;
-- Multiple CTEs with UNION ALL
WITH NewCustomers AS (
SELECT customer_id, 'new' as type FROM customers WHERE created_at >= '2025-01-01'
),
VipCustomers AS (
SELECT customer_id, 'vip' as type FROM customers WHERE total_purchases > 10000
)
SELECT * FROM NewCustomers
UNION ALL
SELECT * FROM VipCustomers;
-- DISTINCT ON to get one employee per department (highest paid)
SELECT DISTINCT ON (department)
department, name, salary
FROM employees
ORDER BY department, salary DESC;
INSERT
, UPDATE
, DELETE
operations (by design - read-only)COUNT
, SUM
, AVG
, etc.)GROUP BY
and HAVING
DENSE_RANK
, LAG
, LEAD
, etc.)cargo test
cargo build --release
cargo run -- -f examples/sample_database.yaml --hot-reload -v
PostgreSQL:
import psycopg2
conn = psycopg2.connect(
host="localhost",
port=5432,
database="test_db",
user="admin",
password="password"
)
cur = conn.cursor()
cur.execute("SELECT * FROM users WHERE is_active = true")
users = cur.fetchall()
MySQL:
import mysql.connector
conn = mysql.connector.connect(
host="127.0.0.1",
port=3306,
database="test_db",
user="admin",
password="password"
)
cur = conn.cursor()
cur.execute("SELECT * FROM users WHERE is_active = true")
users = cur.fetchall()
PostgreSQL:
const { Client } = require('pg');
const client = new Client({
host: 'localhost',
port: 5432,
database: 'test_db',
user: 'admin',
password: 'password',
});
await client.connect();
const res = await client.query('SELECT * FROM users');
MySQL:
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: '127.0.0.1',
port: 3306,
user: 'admin',
password: 'password',
database: 'test_db'
});
connection.query('SELECT * FROM users', (err, results) => {
console.log(results);
});
PostgreSQL:
import (
"database/sql"
_ "github.com/lib/pq"
)
db, err := sql.Open("postgres",
"host=localhost port=5432 user=admin password=password dbname=test_db sslmode=disable")
rows, err := db.Query("SELECT name, email FROM users")
MySQL:
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
db, err := sql.Open("mysql", "admin:password@tcp(127.0.0.1:3306)/test_db")
rows, err := db.Query("SELECT name, email FROM users")
Yamlbase fully supports SQLAlchemy for both PostgreSQL and MySQL protocols:
PostgreSQL:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# Create engine
engine = create_engine('postgresql+psycopg2://admin:password@localhost:5432/test_db')
# For metadata reflection
from sqlalchemy import MetaData, Table
metadata = MetaData()
users_table = Table('users', metadata, autoload_with=engine)
# Direct queries
with engine.connect() as conn:
result = conn.execute("SELECT * FROM users WHERE is_active = true")
users = result.fetchall()
MySQL:
from sqlalchemy import create_engine
# Create engine with PyMySQL driver
engine = create_engine('mysql+pymysql://admin:password@127.0.0.1:3306/test_db')
# Query execution
with engine.connect() as conn:
result = conn.execute("SELECT * FROM users WHERE is_active = true")
users = result.fetchall()
# Note: Yamlbase handles SQLAlchemy's transaction commands (BEGIN, COMMIT, ROLLBACK)
# transparently, even though actual transaction support is not implemented.
Contributions are welcome! Please feel free to submit a Pull Request.
# Run tests
make test
# Run with hot-reload
make run
# Run benchmarks
make bench
# Run all CI checks
make ci
Licensed under either of
at your option.
Yamlbase is inspired by the need for simple, lightweight database solutions for testing and development. Special thanks to all contributors and the Rust community.