2012-07-19 10 views
10

Ho una relazione molti-a-molti tra i post di blog e i tag. Ora voglio sapere quante voci ha un tag specifico.Contare il numero di righe in una relazione molti-a-molti (SQLAlchemy)

immaginare i seguenti modelli (semplificato):

rel_entries_tags = Table('rel_entries_tags', Base.metadata, 
    Column('entry_id', Integer, ForeignKey('entries.id')), 
    Column('tag_id', Integer, ForeignKey('tags.id')) 
) 

class Entry(Base): 
    __tablename__ = 'entries' 

    id = Column(Integer, primary_key=True) 
    title = Column(String(80)) 
    text = Column(Text) 

    tags = relationship('Tag', secondary=rel_entries_tags, backref=backref('entries')) 

    def __init__(self, title, text): 
    self.title = title 
    self.text = text 
    self.tags = tags  

class Tag(Base): 
    __tablename__ = 'tags' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(80), unique=True, nullable=False) 

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

Il mio approccio a contare la quantità di voci per un tag è len(db_session.query(Tag).get(1).entries). Il problema è che quando diventa db_session.query(Tag).get(1).entries SQLAlchemy seleziona tutte le voci con tutte le loro colonne per un tag, tuttavia, voglio solo la quantità delle voci, non le voci stesse. C'è un approccio più ottimale per questo problema?

Grazie.

risposta

15
session.query(Entry).join(Entry.tags).filter(Tag.id==1).count() 

o se si dispone di un tag già

session.query(Entry).with_parent(mytag, "entries").count() 
+4

+1: e se avete bisogno di questo, spesso, è possibile creare una proprietà: '@property \ n def entries_cnt (self): \ n return Session.object_session (self) .query (Entry) .with_parent (self, "entries"). count() ' – van

+0

Grazie per questa risposta. Tuttavia, l'istruzione SQL prodotta è 'SELECT count (*) AS count_1 FROM (SELECT order_line.id AS order_line_id, order_line.order_id AS order_line_order_id FROM order_line WHERE% (param_1) s = order_line.order_id) AS anon_1' In altre parole - invece di un 'SELECT count (*) FROM order_line WHERE order_line.order_id =% (param_1) s' otteniamo un SELECT interno. Nel mio caso, non è uno a molti (l'ordine ha molti ordini). – guyarad

+0

fare una query (func.count ('*')) in primo piano. la [count() documentation] (http://docs.sqlalchemy.org/en/latest/orm/query.html?highlight=query.count#sqlalchemy.orm.query.Query.count) fa riferimento a questo. – zzzeek

Problemi correlati