5

モデルに次の関係を設定しています。

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トップクラスのプロファイルでは問題なく動作し、再帰する必要があるリストがあると判断しました。

# 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

これは最適に見えないため、より良い方法があれば教えてください。

4

3 に答える 3

3

__relationships__クラスBaseModelMixinで を として作成できます@property。これには、モデルの後方参照名ではないすべての関係名のリストがあります。

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との2 つのクラスroleがあるので、

>>> p = profile()
>>> p.__relationships__
    # ['roles']

>>> r = role()
>>> r.__relationships__
   # []
于 2015-10-06T18:56:21.257 に答える
3

これがベストプラクティスかどうかはわかりませんが、このコードは私にとってはうまくいきます。属性が参照の場合は True を返し、通常の列タイプの場合は False を返します。

def is_relation(orm_object, attr_name):
    return hasattr(getattr(orm_object.__class__, attr_name).property, 'mapper')
于 2016-04-21T15:48:11.943 に答える
2

見てinspect

例えば

from sqlalchemy import inspect
mapper = inspect(MyModelClass)
# dir(mapper)
# mapper.relationships.keys()
于 2013-08-09T07:38:05.937 に答える