Documentation
14. Python Integration
Use RelPyDB together with normal Python loops, functions, tests, pandas, NumPy and files.
Python-first mental model
RelPyDB is designed to be used from normal Python code. You can build rows in loops, wrap database creation inside functions, use list comprehensions, export to pandas/NumPy, save with pathlib, and combine it with testing tools.
Using RelPyDB inside functions
Put schema creation in one function and data loading in another. This keeps examples, tests and scripts easy to read.
from relpy import RelPy, AutoNumber, col
def build_user_db() -> RelPy:
db = RelPy()
db.create_table("users")
db.add_column("users", "id", AutoNumber, is_primary_key=True)
db.add_column("users", "name", str, nullable=False)
db.add_column("users", "age", int, nullable=False)
return db
def active_adults(db: RelPy):
return (
db.query("users")
.where(col("age") >= 18)
.order_by("name")
.to_list()
)# Reuse in tests
# Reuse in scripts
# Reuse in tutorials
# Keep schema setup separate
# Keep queries readableBuilding rows with loops
RelPyDB works naturally with loops. This is useful when reading from files, APIs, forms, generated data, or test fixtures.
raw_users = [
("Alice", 24),
("Bob", 17),
("Dana", 31),
]
for name, age in raw_users:
db.insert("users", {
"name": name,
"age": age,
})adults = (
db.query("users")
.where(col("age") >= 18)
.pluck("name")
)
print(adults)
# ["Alice", "Dana"]Using list comprehensions and Python transformations
Use to_list() when you want native Python values. Then use normal Python transformations.
rows = db.query("users").to_list()
names = [row["name"].upper() for row in rows]
ages = [row["age"] for row in rows]
average_age = sum(ages) / len(ages)# Better as RelPyDB query:
db.query("users").where(col("age") >= 18)
# Better as Python transformation:
[row["name"].upper() for row in rows]Integration with pandas
Use to_pandas() when you want analysis, plotting, CSV exports or notebook exploration.
df = db.to_pandas("users")
print(df)
print(df.describe())adults_df = df[df["age"] >= 18]
counts = adults_df.groupby("status").size()Integration with NumPy
Use to_numpy() for numerical pipelines. For one column, pass column_name to get a 1D array.
amounts = db.to_numpy("orders", column_name="amount", dtype=float)
print(amounts.mean())
print(amounts.max())Integration with JSON and files
to_json() is public export. save() is full RelPyDB persistence. They serve different goals.
json_text = db.to_json("users", indent=2)
Path("users_export.json").write_text(json_text)db.save("database.relpy.json")
loaded = RelPy.load("database.relpy.json")Integration with tests
A common pattern is to create a small in-memory database inside a test.
def test_paid_orders_are_returned():
db = build_shop_db()
result = (
db.query("orders")
.where(col("status") == "paid")
.count()
)
assert result == 2Integration with dataclasses
You can convert application objects into rows before insert, and export rows back into dataclasses.
from dataclasses import dataclass, asdict
@dataclass
class UserInput:
name: str
age: int
user = UserInput("Alice", 24)
db.insert("users", asdict(user))
rows = db.to_list("users")Integration checklist
| Goal | Recommended function | Why |
|---|---|---|
| Use rows in Python logic | to_list() | Native dictionaries and lists. |
| Analyze in notebooks | to_pandas() | DataFrame workflows. |
| Numerical processing | to_numpy() | Arrays and vector operations. |
| Send public data | to_json() | Text format, masks encrypted values by default. |
| Restore RelPyDB object later | save() / load() | Schema, data, indexes and internal row ids. |
| Move data to SQL table | to_sql() | Generates INSERT INTO statements. |