如何为sqlacodegen生成的Base类添加功能或创建父类?
嘿,刚好我对SQLAlchemy的declarative base这块比较熟,来给你拆解这两个问题,还有通用代码的放置建议:
1)直接给Base类添加功能
sqlacodegen生成的所有表类都继承自Base,所以直接给这个Base添加通用方法/属性就行,但要注意标记它为抽象类,避免SQLAlchemy把它当成数据库表来映射。
举个实际的例子,我们给Base加通用的保存、删除方法,还有更友好的__repr__:
from sqlalchemy.ext.declarative import declarative_base # 先创建基础的Base Base = declarative_base() # 继承原Base并添加通用功能,标记为抽象类 class Base(Base): __abstract__ = True # 必须!告诉SQLAlchemy这不是一个具体的表 def save(self, session): """通用保存方法:添加到会话并提交""" session.add(self) session.commit() def delete(self, session): """通用删除方法:从会话移除并提交""" session.delete(self) session.commit() def __repr__(self): """自动生成包含主键的类表示,方便调试""" pk_cols = [col.name for col in self.__table__.primary_key.columns] pk_info = {col: getattr(self, col) for col in pk_cols} return f"<{self.__class__.__name__} {pk_info}>"
之后sqlacodegen生成的MyFirstClass、MySecondClass继承这个Base后,就自动拥有这些通用方法了。
2)给Base创建父类来添加功能
如果想把通用逻辑和SQLAlchemy的基础Base解耦,或者拆分不同的功能模块,可以用Mixin类作为Base的父类。
比如我们先定义一个包含通用序列化、查询功能的Mixin:
from sqlalchemy.ext.declarative import declarative_base # 定义通用功能的Mixin类,同样标记为抽象类 class BaseMixin: __abstract__ = True def to_dict(self): """把表对象转化为字典,方便接口返回""" return {col.name: getattr(self, col.name) for col in self.__table__.columns} @classmethod def get_by_id(cls, session, pk_value): """根据主键查询单条数据的通用类方法""" return session.query(cls).get(pk_value) # 让SQLAlchemy的Base继承这个Mixin Base = declarative_base(cls=BaseMixin)
这样生成的所有表类继承Base后,就会拥有to_dict()和get_by_id()这些方法。如果有多个功能模块,还可以创建多个Mixin,让Base多继承(比如declarative_base(cls=(BaseMixin, TimestampMixin))),非常灵活。
通用代码的放置位置
建议把这些通用Base/Mixin代码单独放在一个文件里,比如core/base_models.py,这样所有生成的表类都可以统一导入这个Base:
- 编写好
base_models.py后,用sqlacodegen的--base-class参数指定自定义的Base,生成命令示例:
sqlacodegen postgresql://user:password@localhost/your_db --base-class core.base_models.Base > models.py
- 生成后的
models.py里会自动变成from core.base_models import Base,而不是自己定义Base,完美衔接你的通用逻辑。 - 后续如果要扩展通用功能,直接修改
base_models.py就行,所有表类都会自动继承更新后的功能,不用一个个修改生成的代码。
内容的提问来源于stack exchange,提问作者Barka
相关产品推荐
相关产品推荐

