RpRelPyDBRelational Python

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.

Good rule: use RelPyDB for relational structure, and use regular Python for application logic around it.

Using RelPyDB inside functions

Put schema creation in one function and data loading in another. This keeps examples, tests and scripts easy to read.

Python function
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()
    )
Why this is useful
# Reuse in tests
# Reuse in scripts
# Reuse in tutorials
# Keep schema setup separate
# Keep queries readable

Building rows with loops

RelPyDB works naturally with loops. This is useful when reading from files, APIs, forms, generated data, or test fixtures.

Loop input
raw_users = [
    ("Alice", 24),
    ("Bob", 17),
    ("Dana", 31),
]

for name, age in raw_users:
    db.insert("users", {
        "name": name,
        "age": age,
    })
Query after loop
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.

Export to Python
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)
When to prefer RelPyDB methods
# 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.

RelPyDB to pandas
df = db.to_pandas("users")

print(df)
print(df.describe())
Typical pandas continuation
adults_df = df[df["age"] >= 18]
counts = adults_df.groupby("status").size()
Tip: use RelPyDB to enforce relational rules first. Use pandas when you want analysis-oriented operations.

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.

Public JSON export
json_text = db.to_json("users", indent=2)
Path("users_export.json").write_text(json_text)
RelPyDB object persistence
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 == 2

Integration 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

GoalRecommended functionWhy
Use rows in Python logicto_list()Native dictionaries and lists.
Analyze in notebooksto_pandas()DataFrame workflows.
Numerical processingto_numpy()Arrays and vector operations.
Send public datato_json()Text format, masks encrypted values by default.
Restore RelPyDB object latersave() / load()Schema, data, indexes and internal row ids.
Move data to SQL tableto_sql()Generates INSERT INTO statements.