我在模型中设置了以下关系:
role_profiles = Table('roleprofile', Base.metadata,
Column('role_id', Integer, ForeignKey('role.id')),
Column('profile_id', Integer, ForeignKey('profile.id'))
)
class profile(Base):
__tablename__ = 'profile'
# Columns...
roles = relationship('role', secondary=role_profiles, backref='profiles')
class role(Base):
__tablename__ = 'role'
# Columns...
因此,我现在明白它的工作原理是配置文件对象上的roles属性将包含一个角色类列表(它所做的)。
我想要做的是一般地为模型类的每个属性序列化。它适用于顶级类配置文件,我确定有一个roles
列表,我应该进入:
# I need a statement here to check if the field.value is a backref
#if field.value is backref:
# continue
if isinstance(field.value, list):
# Get the json for the list
value = serialize.serialize_to_json(field.value)
else:
# Get the json for the value
value = cls._serialize(field.value)
问题是关系的backref
会将指针添加回配置文件。然后序列化相同的配置文件,它反复递归角色,直到stack overflow
。
有没有办法确定该属性是backref
添加的relationship
?
更新
也许我应该补充一点,如果我删除backref
,因为我不需要它,但是我想保留它。
更新
作为临时修复,我向我的基类添加了一个类属性:
class BaseModelMixin(object):
"""Base mixin for models using stamped data"""
__backref__ = None
并像这样添加:
class role(Base):
__tablename__ = 'role'
__backref__ = ('profiles', )
# Columns...
并在我的递归中使用它:
if self.__backref__ and property_name in self.__backref__:
continue
如果有更好的方法请告诉我,因为这看起来并不理想。
答案 0 :(得分:3)
您可以在班级__relationships__
中创建BaseModelMixin
作为@property
,其中包含所有关系名称的列表,这些关系名称不是模型中的backref名称。
class BaseModelMixin(object):
"""Base mixin for models using stamped data"""
@property
def __relationships__(self):
"""
Return a list of relationships name which are not as a backref
name in model
"""
back_ref_relationships = list()
items = self.__mapper__.relationships.items()
for (key, value) in items:
if isinstance(value.backref, tuple):
back_ref_relationships.append(key)
return back_ref_relationships
由于您有两个课程profile
和role
,所以
>>> p = profile()
>>> p.__relationships__
# ['roles']
>>> r = role()
>>> r.__relationships__
# []
答案 1 :(得分:3)
不确定这是否是最佳做法,但此代码适用于我。如果属性是引用,则返回True;如果是常规列类型,则返回False。
def is_relation(orm_object, attr_name):
return hasattr(getattr(orm_object.__class__, attr_name).property, 'mapper')
答案 2 :(得分:2)
查看inspect
e.g。
from sqlalchemy import inspect
mapper = inspect(MyModelClass)
# dir(mapper)
# mapper.relationships.keys()