sqlalchemy自我引用关系,不包括\'self\'

问题描述

| 我有一个简单的数据结构,其中电影表具有国家表的外键。 为了检索来自同一国家的所有电影,我具有此属性'same_country_films \',这是一种自指关系。 它几乎可以正确地完成工作,但是,它也将电影本身包括在列表中。如何排除其他电影? 非常感谢!
from sqlalchemy import Table,Column,Integer,String,MetaData,ForeignKey 
from sqlalchemy.orm import mapper,relationship
Metadata = MetaData()
country_table = Table(\'country\',Metadata,Column(\'id\',primary_key=True),Column(\'name\',String),)
film_table = Table(\'film\',Column(\'title\',Column(\'year\',Integer),Column(\'country_id\',ForeignKey(\'country.id\'))
    )

class Country(object):
    pass

class Film(object):
    pass

mapper(Country,country_table)

mapper(Film,film_table,properties={
            \'country\':relationship(
                    Country,backref=\'films\'),\'same_country_films\':relationship(
                    Film,primaryjoin=film_table.c.country_id==\\
                                film_table.c.country_id,foreign_keys=[
                        film_table.c.country_id,]
                    )
             }
    )
    

解决方法

最简单的解决方案是自己编写此属性而不是关联代码:
class Film(object):
    @property
    def same_country_films(self):
        return [f for f in self.country.films if f!=self]
当在会话期间访问
film.same_country_films
country.films
时,此解决方案将不会对此属性进行单独查询。无法像平常使用关系那样更新该属性,但是我怀疑它是否确实需要。 不好的是它是针对每次访问进行评估的(工作量不大)。您可以将
property
装饰器更改为chaching一个(例如werkzeug中的ѭ5)),但是该属性在首次访问
country.films
后不会反映出更改。     ,我认为应该这样做(尽管我尚未实际测试过):
primaryjoin=sqlalchemy.and_(
    film_table.c.country_id==film_table.c.country_id,film_table.c.id!=film_table.c.id)