簡體   English   中英

sqlalchemy多對多,但是相反嗎?

[英]sqlalchemy many-to-many, but inverse?

很抱歉,如果反向不是首選的術語,可能會妨礙我的搜索。 無論如何,我要處理兩個sqlalchemy聲明性類,這是一個多對多關系。 第一個是Account,第二個是Collection。 用戶“購買”了集合,但是我想顯示用戶尚未購買的前10個集合。

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)

因此,使用account.collections可以獲得所有集合,並且使用dyn_coll.limit(1).all()可以將查詢應用於集合列表...但是我該如何做逆運算呢? 我想獲取該帳戶尚未映射的前10個收藏集。

任何幫助都令人感激。 謝謝!

我不會為此目的使用該關系,因為從技術上講,它不是您正在建立的關系(因此,保持雙方同步的所有技巧都將失效)。
IMO,最干凈的方法是定義一個簡單的查詢,該查詢將返回您要查找的對象:

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()
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM