【问题标题】:sqlalchemy self referential relationship not including 'self'sqlalchemy 自引用关系不包括“自我”
【发布时间】:2011-04-14 16:54:10
【问题描述】:

我有一个简单的数据结构,其中一个电影表有一个国家表的外键。

为了检索来自同一个国家的所有电影,我有这个属性'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', String, primary_key=True),
    Column('name', String),
    )
film_table = Table('film', metadata,
    Column('id', Integer, primary_key=True),
    Column('title', String),
    Column('year', Integer),
    Column('country_id', Integer, 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,
                        ]
                    )
             }
    )

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    最简单的解决方案是自己编写这个属性而不是关系:

    class Film(object):
        @property
        def same_country_films(self):
            return [f for f in self.country.films if f!=self]
    

    当在会话期间同时访问 film.same_country_filmscountry.films 时,此解决方案不会对此属性进行单独查询。该属性无法像您通常对关系所做的那样更新,但我怀疑它是否真的需要。

    不好的是,每次访问都会对其进行评估(工作量不大)。您可以将 property 装饰器更改为 chaching 装饰器(如 werkzeug 中的 cached_property),但在首次访问该属性后,该属性不会反映 country.films 中的更改。

    【讨论】:

    • 感谢您的回答。这是解决所提出问题的好方法。老实说,我真正的目的是用这个电影国家的例子来探索关系是如何运作的。是否有可能使用关系来解决问题?
    【解决方案2】:

    我认为应该这样做,(虽然我还没有实际测试过):

    primaryjoin=sqlalchemy.and_(
        film_table.c.country_id==film_table.c.country_id,
        film_table.c.id!=film_table.c.id)
    

    【讨论】:

    • 不完全。它不会将 film_table.c.id 替换为 ?在生成的sql中。
    猜你喜欢
    • 2011-07-20
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 2011-05-09
    相关资源
    最近更新 更多