无法为SQLAlchemy的MappedColumn添加自定义属性_editable,触发AttributeError
解决SQLAlchemy MappedColumn添加自定义属性的AttributeError问题
错误原因
SQLAlchemy的MappedColumn类通过__slots__机制限制了实例允许拥有的属性列表,类定义中没有预定义_editable属性,因此直接给实例赋值该属性会触发AttributeError。
解决方案一:利用原生info参数存储自定义属性(推荐)
SQLAlchemy的mapped_column支持info参数,专门用于存储自定义元数据,完全符合框架设计规范,兼容性拉满:
from typing import Any from sqlalchemy.orm import mapped_column as mc from sqlalchemy.orm.properties import MappedColumn from sqlalchemy import Integer, String def mapped_column(*args, editable=True, **kwargs) -> MappedColumn[Any]: # 把editable参数存入info字典,没有info则先初始化 kwargs.setdefault('info', {})['editable'] = editable return mc(*args, **kwargs) # 使用示例 class User(Base): __tablename__ = 'users' id = mapped_column(Integer, primary_key=True, editable=False) name = mapped_column(String(50)) # 访问自定义属性 print(User.__table__.c.name.info['editable']) # 输出 True print(User.__table__.c.id.info['editable']) # 输出 False
解决方案二:子类化MappedColumn(无需复制全部构造函数)
如果你坚持要通过实例属性直接访问,不需要复制原构造函数全部内容,只需在子类中传递所有参数给父类即可:
from typing import Any from sqlalchemy.orm import mapped_column as mc from sqlalchemy.orm.properties import MappedColumn from sqlalchemy import Integer, String class EditableMappedColumn(MappedColumn): def __init__(self, *args, editable=True, **kwargs): super().__init__(*args, **kwargs) self._editable = editable def mapped_column(*args, editable=True, **kwargs) -> EditableMappedColumn[Any]: return EditableMappedColumn(*args, editable=editable, **kwargs) # 使用示例 class User(Base): __tablename__ = 'users' id = mapped_column(Integer, primary_key=True, editable=False) name = mapped_column(String(50)) # 访问自定义属性 print(User.id.property._editable) # 输出 False print(User.name.property._editable)# 输出 True
内容的提问来源于stack exchange,提问作者user17463321
相关产品推荐
相关产品推荐

