2010-10-21 24 views
5

Eğer inverse, aramamı engelleyebilecek tercih edilen isimlendirme değilse özür dilerim. Her durumda, bir çoktan çoğa ilişkisi olan iki sqlchchle bildirge sınıfıyla uğraşıyorum. Birincisi Hesap, ikincisi ise Koleksiyon. Kullanıcılar "satın alma" koleksiyonları, ancak ilk 10 koleksiyonunu göstermek istiyorum kullanıcı henüz satın alınmış değil satın aldı.sqlalchemy çok-çok, ama ters?

from sqlalchemy import * 
from sqlalchemy.orm import scoped_session, sessionmaker, relation 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 

engine = create_engine('sqlite:///:memory:', echo=True) 
Session = sessionmaker(bind=engine) 

account_to_collection_map = Table('account_to_collection_map', Base.metadata, 
           Column('account_id', Integer, ForeignKey('account.id')), 
           Column('collection_id', Integer, ForeignKey('collection.id'))) 

class Account(Base): 
    __tablename__ = 'account' 

    id = Column(Integer, primary_key=True) 
    email = Column(String) 

    collections = relation("Collection", secondary=account_to_collection_map) 

    # use only for querying? 
    dyn_coll = relation("Collection", secondary=account_to_collection_map, lazy='dynamic') 

    def __init__(self, email): 
     self.email = email 

    def __repr__(self): 
     return "<Acc(id=%s email=%s)>" % (self.id, self.email) 

class Collection(Base): 
    __tablename__ = 'collection' 

    id = Column(Integer, primary_key=True) 
    slug = Column(String) 

    def __init__(self, slug): 
     self.slug = slug 

    def __repr__(self): 
     return "<Coll(id=%s slug=%s)>" % (self.id, self.slug) 

Yani, account.collections ile, tüm koleksiyonları alabilirsiniz ve dyn_coll.limit (1) .all() ile Ben koleksiyonların listesine sorguları uygulayabilirsiniz ... ama nasıl yapacağım ters? Hesabın 'un değil eşlemesi yapıldığı ilk 10 koleksiyonunu almak istiyorum.

Her türlü yardım inanılmaz derecede takdir edilmektedir. Teşekkürler!

cevap

5

Bu amaçla ilişkiyi teknik olarak kullanmamaya çalıştığınız bir ilişki olarak kullanmıyorum (böylece her iki tarafta da senkronize olmanın tüm hileleri işe yaramayacaktır).

class Account(Base): 
    ... 
    # please note added *backref*, which is needed to build the 
    #query in Account.get_other_collections(...) 
    collections = relation("Collection", secondary=account_to_collection_map, backref="accounts") 

    def get_other_collections(self, maxrows=None): 
     """ Returns the collections this Account does not have yet. """ 
     q = Session.object_session(self).query(Collection) 
     q = q.filter(~Collection.accounts.any(id=self.id)) 
     # note: you might also want to order the results 
     return q[:maxrows] if maxrows else q.all() 
... 
+0

Huh:
IMO, en temiz yolu size aradığınız nesneleri döndürür basit bir sorgu tanımlamak olacaktır. Açıkçası, sqlalchemy hakkında öğrenecek çok şeyim var. :) Teşekkürler! – Hoopes