2011-02-01 26 views
5

SQLAlchemy konusunda yeniyim ve bu tür tabloları tanımlamak için en iyi yolun ne olacağını merak ediyordum. Bir kullanıcıdan user.groups, bir gruptaki kullanıcılara group.users tarafından erişmek ve bir gruptaki bir kullanıcının rolünü öğrenmek istiyorum (bir ilişkilendirme modelinde mantıksal olarak tanımlanacağını varsayalım). Ayrıca tüm kullanıcıları seçmek, gruba göre gruplamak ve rol başlıkları eklemek istiyorum.Kullanıcılara, gruplara ve rollere ilişkin çoktan çoğa beyanı SQLAcchemy tanımları

, ben birleştirme tablosunu (bildirim tarzı) oluşturmak için öğretici kullanarak ve User ve Group sınıflarında relationship özellikleri secondary argüman çıkarmadan denedim ama sonra kullanıcılardan doğrudan gruplara erişme yeteneğini kaybeder ve Kullanıcılar doğrudan gruplardan (ilişkilendirme tablosundaki backref'lar ilişkilendirme sınıfının kendisine işaret eder: /).

Herhangi bir yardım için teşekkür ederiz.

+0

* role * basit bir etiket (sütun) veya ilişkinin başka bir anahtar niteliği ve PK ilişkisinin bir parçası mı? İlgili: Bir kullanıcı aynı grupta birden fazla role sahip olabilir mi? – van

+0

Evet, rol bir sütundur. Muhtemelen yerine pozisyon seçilmelidir. – dav

+0

Bir kullanıcı aynı grupta birden fazla rol/pozisyona sahip olabilir mi? – van

cevap

7

Modelinizi basitleştirmenin anahtarı, associationproxy numaralı telefonu kullanmaktır, bu nedenle mutlaka bir göz atın. Aşağıdaki kod tüm sorularınıza cevap gerektiğini kullanıcı bir grup içindeki tek rol sahip olabileceğini varsayarsak
: modeli ve ilişkileri nasıl yapılandırılacağı

  • nasıl ekleneceği/kaldır/Eğer

sen modeli kısmı üzerinde almalı istedi roller verileri (raporları) nasıl alınacağını

  • güncelleme ve r unutmak Avustralya, Brezilya ve Kuzey Amerika ülkelerinin kullandığı saat uygulaması. Tamamen içerilmiş ve aşağıdaki betik aşağıdadır:

    from sqlalchemy import create_engine, Column, Integer, Unicode, ForeignKey 
    from sqlalchemy.orm import relationship, scoped_session, sessionmaker 
    from sqlalchemy.orm.collections import attribute_mapped_collection 
    from sqlalchemy.ext.declarative import declarative_base 
    from sqlalchemy.ext.associationproxy import association_proxy 
    
    # Configure test data SA 
    engine = create_engine(u'sqlite:///:memory:', echo=False) 
    session = scoped_session(sessionmaker(bind=engine, autoflush=False)) 
    Base = declarative_base() 
    
    class _BaseMixin(object): 
        """ 
        A helper mixin class to set properties on object creation. 
    
        Also provides a convenient default __repr__() function, but be aware that 
        also relationships are printed, which might result in loading the relation 
        objects from the database 
        """ 
        def __init__(self, **kwargs): 
         for k, v in kwargs.items(): 
          setattr(self, k, v) 
    
        def __repr__(self): 
         return "<%s(%s)>" % (self.__class__.__name__, 
          ', '.join('%s=%r' % (k, self.__dict__[k]) 
             for k in sorted(self.__dict__) 
             if '_' != k[0] 
             #if '_sa_' != k[:4] and '_backref_' != k[:9] 
            ) 
          ) 
    
    
    # relation creator factory functions 
    def _creator_gr(group, role): 
        res = UserGroup(group=group, role=role) 
        return res 
    def _creator_ur(user, role): 
        res = UserGroup(user=user, role=role) 
        return res 
    
    ############################################################################## 
    # Object Model 
    ############################################################################## 
    class Role(Base, _BaseMixin): 
        __tablename__ = 'roles' 
        # columns 
        id = Column(Integer, primary_key=True, autoincrement=True) 
        name = Column(Unicode(16), unique=True) 
        # relations 
        usergroup = relationship("UserGroup", backref='role') 
    
    class User(Base, _BaseMixin): 
        __tablename__ = 'users' 
        # columns 
        id = Column(Integer, primary_key=True, autoincrement=True) 
        name = Column(Unicode(16), unique=True) 
        # relations 
        _rel_usergroup = relationship("UserGroup", collection_class=attribute_mapped_collection('group'), 
                cascade='all,delete-orphan', 
                backref='user', 
               ) 
        groups = association_proxy('_rel_usergroup', 'role', creator=_creator_gr) 
    
    class Group(Base, _BaseMixin): 
        __tablename__ = 'groups' 
        # columns 
        id = Column(Integer, primary_key=True, autoincrement=True) 
        name = Column(Unicode(16), unique=True) 
        # relations 
        _rel_usergroup = relationship("UserGroup", collection_class=attribute_mapped_collection('user'), 
                cascade='all,delete-orphan', 
                backref='group', 
               ) 
        users = association_proxy('_rel_usergroup', 'role', creator=_creator_ur) 
    
    class UserGroup(Base, _BaseMixin): 
        __tablename__ = 'user_group' 
        # columns 
        id = Column(Integer, primary_key=True, autoincrement=True) 
        user_id = Column(Integer, ForeignKey('users.id', ondelete='CASCADE'), nullable=False) 
        group_id = Column(Integer, ForeignKey('groups.id', ondelete='CASCADE'), nullable=False) 
        role_id = Column(Integer, ForeignKey('roles.id', ondelete='CASCADE'), nullable=False) 
        # relations 
        # (all backrefs) 
    
    
    
    ############################################################################## 
    # TESTS (showing usages) 
    # 
    # Requirements: 
    # - list all groups of the user: user.groups (use keys) 
    # - list all users of the group: group.users (use keys) 
    # - get all users ordered (grouped) by group with the role title 
    ############################################################################## 
    
    def _requirement_get_user_groups(user): 
        return user.groups.keys() 
    
    def _requirement_get_group_users(group): 
        return group.users.keys() 
    
    def _requirement_get_all_users_by_group_with_role(): 
        qry = session.query(Group).order_by(Group.name) 
        res = [] 
        for g in qry.all(): 
         for u, r in sorted(g.users.items()): 
          value = (g.name, u.name, r.name) 
          res.append(value) 
        return res 
    
    def _test_all_requirements(): 
        print '--requirement: all-ordered:' 
        for v in _requirement_get_all_users_by_group_with_role(): 
         print v 
    
        print '--requirement: user-groups:' 
        for v in session.query(User).order_by(User.id): 
         print v, " has groups: ", _requirement_get_user_groups(v) 
    
        print '--requirement: group-users:' 
        for v in session.query(Group).order_by(Group.id): 
         print v, " has users: ", _requirement_get_group_users(v) 
    
    # create db schema 
    Base.metadata.create_all(engine) 
    
    ############################################################################## 
    # CREATE TEST DATA 
    ############################################################################## 
    
    # create entities 
    u_peter = User(name='u_Peter') 
    u_sonja = User(name='u_Sonja') 
    g_sales = Group(name='g_Sales') 
    g_wales = Group(name='g_Wales') 
    r_super = Role(name='r_Super') 
    r_minor = Role(name='r_Minor') 
    
    # helper functions 
    def _get_entity(entity, name): 
        return session.query(entity).filter_by(name=name).one() 
    def get_user(name): 
        return _get_entity(User, name) 
    def get_group(name): 
        return _get_entity(Group, name) 
    def _checkpoint(): 
        session.commit() 
        session.expunge_all() 
        _test_all_requirements() 
        session.expunge_all() 
        print '-' * 80 
    
    
    # test: **ADD** 
    u_peter.groups[g_wales] = r_minor # add 
    g_wales.users[u_sonja] = r_super # add 
    g_sales.users[u_peter] = r_minor # add 
    session.add(g_wales) 
    #session.add(g_sales) 
    _checkpoint() 
    
    # test: **UPDATE** 
    u_peter = get_user('u_Peter') 
    assert u_peter.name == 'u_Peter' and len(u_peter.groups) == 2 
    assert len(u_peter.groups) == 2 
    g_wales = get_group('g_Wales') 
    g_wales.users[u_peter] = r_super # update 
    _checkpoint() 
    
    # test: **DELETE** 
    u_peter = get_user('u_Peter') 
    assert u_peter.name == 'u_Peter' and len(u_peter.groups) == 2 
    g_wales = get_group('g_Wales') 
    del u_peter.groups[g_wales] # delete 
    _checkpoint() 
    
  • +1

    Hey. Benzer bir şey yapmak istedim. InvalidRequestError: eski dernek proxy'si, ana nesne kapsam dışında kaldım. Sebebi ne olabilir? –

    +0

    Bu hatayla hiç karşılaşmadım, bu yüzden burada tahmin ediyorum: belki nesnelerden biri başka bir oturuma ait mi? – van

    +0

    Hey, nesneler düzgün şekilde ekleniyor. Sadece veritabanını kontrol ettim. Ayrıca nesneleri düzgün bir şekilde alabiliyorum, ancak tekrar sorgulamam gerekiyor. Soru için üzgünüm. –

    İlgili konular