求推荐兼容mypy的Python类型安全函数关系映射(FRM)框架
Python中类似Scala Slick的函数关系映射(FRM)框架推荐
你想要的是基于数据类(dataclass)、支持声明式查询(类似生成器推导式)、可静态类型检查并自动生成SQL的FRM框架,以下是几个现有项目可以参考:
1. SQLAlchemy 2.0+
SQLAlchemy是Python生态中最成熟的ORM/FRM工具,2.0版本后对类型注解和数据类的支持大幅增强,完全匹配你的核心需求:
- 数据类风格模型定义:可以直接用
@dataclass结合映射工具,或使用内置的DeclarativeBase配合类型注解定义模型(底层兼容dataclass)from sqlalchemy import Integer, String, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column class Base(DeclarativeBase): pass class Student(Base): __tablename__ = "students" student_id: Mapped[int] = mapped_column(Integer, primary_key=True) name: Mapped[str] = mapped_column(String) class Course(Base): __tablename__ = "courses" course_id: Mapped[int] = mapped_column(Integer, primary_key=True) title: Mapped[str] = mapped_column(String) student_id: Mapped[int] = mapped_column(ForeignKey("students.student_id")) - 声明式查询与SQL生成:使用
select表达式构建查询,语法接近Python推导式,支持mypy静态检查,自动生成目标SQL:from sqlalchemy import select from sqlalchemy.orm import Session def get_student_courses(session: Session): stmt = select(Student.name, Course.title).join(Course, Student.student_id == Course.student_id) # 生成的SQL与你示例完全一致 result = session.execute(stmt) return ((name, title) for name, title in result)
2. Peewee
Peewee是轻量级ORM,语法简洁,支持数据类和类型注解,查询风格贴近Python原生写法:
- 数据类模型定义:用
@dataclass装饰Peewee模型,或配合内置字段类型实现:from peewee import Model, IntegerField, CharField, ForeignKeyField, SqliteDatabase from dataclasses import dataclass db = SqliteDatabase(':memory:') @dataclass class Student(Model): student_id = IntegerField(primary_key=True) name = CharField() class Meta: database = db @dataclass class Course(Model): course_id = IntegerField(primary_key=True) title = CharField() student_id = ForeignKeyField(Student, backref='courses') class Meta: database = db - 声明式查询:链式调用构建查询,结果可生成迭代器,自动转换为SQL:
def get_student_courses(): query = (Student .select(Student.name, Course.title) .join(Course) .where(Student.student_id == Course.student_id)) # 生成目标SQL return ((s.name, c.title) for s, c in query.tuples())
3. Tortoise-ORM
异步优先的ORM,完全基于类型注解和声明式模型,适合异步场景:
- 数据类风格模型:使用
models.Model配合类型注解,写法与dataclass高度一致:from tortoise.models import Model from tortoise import fields class Student(Model): student_id = fields.IntField(pk=True) name = fields.CharField(max_length=100) class Meta: table = "students" class Course(Model): course_id = fields.IntField(pk=True) title = fields.CharField(max_length=100) student_id = fields.ForeignKeyField("models.Student", related_name="courses") class Meta: table = "courses" - 异步声明式查询:链式查询语法返回异步迭代器,自动生成SQL:
async def get_student_courses(): query = Student.all().values_list("name", "course__title").join(Course) # 生成对应SQL async for name, title in query: yield (name, title)
4. Django ORM(配合django-stubs)
若在Django生态开发,Django ORM也可满足需求:
- 数据类兼容:用
@dataclass装饰Django模型,或配合内置字段类型:from django.db import models from dataclasses import dataclass @dataclass class Student(models.Model): student_id = models.IntegerField(primary_key=True) name = models.CharField(max_length=100) @dataclass class Course(models.Model): course_id = models.IntegerField(primary_key=True) title = models.CharField(max_length=100) student_id = models.ForeignKey(Student, on_delete=models.CASCADE) - 声明式查询:链式查询语法,通过
django-stubs支持静态类型检查:def get_student_courses(): query = Student.objects.values_list("name", "course__title").select_related("course") # 生成目标SQL return ((name, title) for name, title in query)
关于生成器推导式直接转SQL
目前上述框架都未实现直接将Python生成器推导式转换为SQL的功能(这也是你概念验证项目的核心价值),但它们的查询API都尽可能贴近Python原生语法,且支持静态类型检查、自动生成高效SQL。如果需要完全匹配推导式写法,可基于现有框架扩展,或继续完善你的概念验证项目。
内容的提问来源于stack exchange,提问作者Peewee 733
相关产品推荐
相关产品推荐

