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.
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.