Skip to content

Latest commit

 

History

History
55 lines (40 loc) · 1.83 KB

README.md

File metadata and controls

55 lines (40 loc) · 1.83 KB

py-frm

This repo illustrates a proof-of-concept type-safe functional-relational mapping framework for Python inspired by Slick. The idea is that we can work with relational databases as if we are working with Python collections and dataclasses. Moreover we can use mypy to provide type-safety.

If you would like to see this project turned into a fully capable production-ready SDK, please star this repository and consider contributing by submitting issues and PRs.

Illustrative end-user code

Our database model is represented using Python dataclasses, e.g.:

from dataclasses import dataclass, field
from py_frm import sqlalchemy_model


@sqlalchemy_model(table="students")
@dataclass
class Student:
    student_id: int = field(metadata={"primary_key": True})
    name: str


@sqlalchemy_model(table="courses")
@dataclass
class Course:
    course_id: int = field(metadata={"primary_key": True})
    title: str
    student_id: int = field(metadata={"foreign_key": ("students", "student_id")})

Database queries are written as type-annotated Python generators using generator comprehensions:

from typing import Iterable, Generator, Tuple


def get_student_courses(
    students: Iterable[Student], courses: Iterable[Course]
) -> Generator[Tuple[str, str], None, None]:
    return (
        (s.name, c.title)
        for s in students
        for c in courses
        if s.student_id == c.student_id
    )

The above type-annotated function can be statically checked by mypy, and is automatically mapped onto the corresponding SQL query:

SELECT students.name, courses.title 
FROM students, courses 
WHERE students.student_id = courses.student_id;

See the example for the complete runnable code.