SqlAlchemy: получение экземпляров определенного типа в отношениях, которые могут содержать объекты нескольких типов. - PullRequest
0 голосов
/ 16 мая 2011

У меня есть приложение с классом «BaseVisibilizer», который является базовым классом для двух других классов:

class BaseVisibilizer(declarativeBase):
       __tablename__ = "base_visibilizers"
       _polymorphicIdentity = Column("polymorphic_identity", String(20), key="polymorphicIdentity")
       __mapper_args__ = {
               'polymorphic_on': _polymorphicIdentity,
               'polymorphic_identity': None
       }

       def __init__(self):
               super(BaseVisibilizer, self).__init__()

Это базовый класс для моих классов User и UserGroup: оба класса могут бытьиспользуется для управления видимостью определенных элементов.

class UserGroup(BaseVisibilizer.BaseVisibilizer):
       __tablename__ = "user_groups"
       _id = Column("id", Integer, ForeignKey(BaseVisibilizer.BaseVisibilizer.id), primary_key=True)

       __mapper_args__ = {
               'polymorphic_identity': 'UserGroup',
               'inherit_condition': _id == BaseVisibilizer.BaseVisibilizer._id,
       }

       _name = Column("name", String(50), nullable=False)

class User(BaseVisibilizer.BaseVisibilizer):
       __tablename__ = "users"
       _id = Column("id", Integer, ForeignKey(BaseVisibilizer.BaseVisibilizer.id), primary_key=True)

       __mapper_args__ = {
               'polymorphic_identity': 'User',
               'inherit_condition': _id == BaseVisibilizer.BaseVisibilizer._id,
       }
       _firstName = Column("first_name", String(50), key="fistName")
       _lastName = Column("last_name", String(50), key="lastName")
       _userName = Column("user_name", String(50), unique=True, nullable=False)

Во многих других классах моей системы у меня есть отношение, которое может содержать «BaseVisibilizers» (Users или UserGroups).

class Whatever(declarativeBase):
       allowedVisibilizers = relationship("BaseVisibilizer",
               secondary="intermediate_whatevers_to_base_visibilizers",
               collection_class=set)

Таким образом, в случаях Whither набор allowVisibilizers может содержать экземпляры User of UserGroup (поскольку оба являются BaseVisibilizer).Если зарегистрированный пользователь или группа пользователей, к которой принадлежит зарегистрированный пользователь, входит в число «позволенных наблюдателей», то этот пользователь сможет получить доступ (или «увидеть») к этому экземпляру чего угодно.

В определенный момент я быЯ хотел бы создать метод в классе «Какой бы ни был», который бы давал мне только разрешенные визуализаторы, которые фактически являются UserGroup (исключая пользователей), но я не смог этого сделать.

Я пробовал несколько вещей, но, очевидно, не самый правильный (подзапросы, объединения "allowvisibilizers" ...):

What I'd like is something like:
class Whatever(declarativeBase):
       [ . . . ]
       def getAllowedUserGroups(self):
               session = Database.Session()
               query = session.query(UserGroup.UserGroup).filter(UserGroup.UserGroup.in_(self.allowedVisibilizers))
               return query.all()

(но, очевидно, UserGroup является классом и не имеет входной _)

Конечно, я всегда мог получить все «allowVisibilizer» и удалить пользователей из возвращаемого значения, но я пытался немного его оптимизировать и избежать ненужных обращений к базе данных.

Любой намек будет очень признателен.Заранее спасибо!

1 Ответ

0 голосов
/ 17 мая 2011

Одним из решений было бы создание другого отношения на Whatever, которое включало бы фильтр для конкретной таблицы UserGroup, что должно помочь.
Для получения дополнительной информации см. Документацию Несколько отношений с одним и тем же родителем / ребенком . В вашем случае добавление дополнительного условия соединения к таблице UserGroup должно помочь.
Также рассмотрите возможность использования Building Query-Enable-Properties для указания readonly.

...