2011-09-14 10 views
33

私は3つのテーブルを持っています:User、Community、community_members(多くのユーザとコミュニティの関係がたくさんあります)SQLAlchemy追加フィールドを持つManyToManyセカンダリテーブル

私はフラスコSQLAlchemyのを使用して、このテーブルを作成:

community_members = db.Table('community_members', 
       db.Column('id', db.Integer, primary_key=True), 
       db.Column('user_id', db.Integer, db.ForeignKey('user.id')), 
       db.Column('community_id', db.Integer, db.ForeignKey('community.id')), 
       db.Column('time_create', db.DateTime, nullable=False, default=func.now()), 
       ) 

そして今、Pythonシェルで、私はこれを行うことができます:今、私はこのようなcommunity_membersに追加フィールドを追加したい

community_members = db.Table('community_members', 
       db.Column('user_id', db.Integer, db.ForeignKey('user.id')), 
       db.Column('community_id', db.Integer, db.ForeignKey('community.id')), 
       ) 


class Community(db.Model): 
    __tablename__ = 'community' 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(100), nullable=False, unique=True) 
    members = db.relationship(User, secondary=community_members, 
          backref=db.backref('community_members', lazy='dynamic')) 

コミュニティを作成:

> c = Community() 
> c.name = 'c1' 
> db.session.add(c) 
> db.session.commit() 

コミュニティにメンバーを追加します。

> u1 = User.query.get(1) 
> u2 = User.query.get(2) 
> c.members.append(u1) 
> c.members.append(u2) 
> db.session.commit() 

> c.members 
[<User 1>, <User 2>] 

[OK]を、これは動作します。

しかし、今私はcommunity_membersテーブルのtime_createを取得できますか?

答えて

46

単純な多対多関係の使用から、「関連オブジェクト」の使用に切り替える必要があります。これは、基本的に関連テーブルを取得し、適切なクラスマッピングを与えることです。その後、1対多の関係UserCommunityに定義します:

class Membership(db.Model): 
    __tablename__ = 'community_members' 

    id = db.Column('id', db.Integer, primary_key=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id')) 
    community_id = db.Column(db.Integer, db.ForeignKey('community.id')) 
    time_create = db.Column(db.DateTime, nullable=False, default=func.now()) 

    community = db.relationship(Community, backref="memberships") 
    user = db.relationship(User, backref="memberships") 


class Community(db.Model): 
    __tablename__ = 'community' 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(100), nullable=False, unique=True) 

しかし、あなたはたまにしか作成時に興味がある可能性があり、あなたは古い関係を元に戻したい!よく、あなたはrelationshipを2回設定することは望ましくありません。 sqlalchemyはあなたが何らかの形で望んでいると思うので2つのの関連付けがあります。異なるものを意味する必要があります!あなただけ(2などのuser_id =など)、SQLAlchemyのでは、あなたが行うことができ、既知のuser_idによってクエリcommunity_memberscommunityテーブルが必要な場合は、association proxy.

from sqlalchemy.ext.associationproxy import association_proxy 

Community.members = association_proxy("memberships", "user") 
User.communities = association_proxy("memberships", "community") 
+6

私はあなたのソリューションを使用し、それは働いたが、私はまだ問題があります。 Community.members(アソシエーションプロキシで追加されたもの)がAppenderBaseQueryを返す可能性はありますか? Community.members.filter_by(...)?私は関係の宣言でlazy = dynamicを使用してプレーンな多対多の関係でこれを行うのに慣れていましたが、関連テーブルにクラスマッピングを与えた後はもうできません。 – stefanobaldo

+0

解決策@stefanobaldoを発見したことがありましたら、本当に役に立ちました! – pip

0

に追加することによってこれを行うことができます:

session.query(community_members.c.time_create, Community.name).filter(community_members.c.user_id==2)

を結果を得るには

関連する問題