首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQLAlchemy:从特定用户的favorite_series检索所有剧集

SQLAlchemy:从特定用户的favorite_series检索所有剧集
EN

Stack Overflow用户
提问于 2012-05-12 10:40:15
回答 2查看 3.7K关注 0票数 2

我有用户谁可以有他最喜欢的系列,有剧集作为外键,我试图从最喜欢的系列用户检索所有的情节。我用的是水瓶-SQLAlchemy。

数据库:

代码语言:javascript
复制
db = SQLAlchemy(app)

# cross table for user-series
favorite_series = db.Table('favorite_series',
    db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('series_id', db.Integer, db.ForeignKey('series.id'))
)

# user
class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    favorite_series = db.relationship('Series', secondary=favorite_series,
        backref=db.backref('users', lazy='dynamic'))

# series
class Series(db.Model):
     __tablename__ = 'series'
    id = db.Column(db.Integer, primary_key=True)

# episode
class Episode(db.Model):
    __tablename__ = 'episode'
    id = db.Column(db.Integer, primary_key=True)
    series_id = db.Column(db.Integer, db.ForeignKey('series.id'))
    series = db.relationship('Series',
        backref=db.backref('episodes', lazy='dynamic'))

朋友帮助我使用SQL

代码语言:javascript
复制
select user_id,series.name,episode.name from (favorite_series left join series on favorite_series.series_id = series.id) left join episode on episode.series_id = series.id where user_id=1;

尽管如此,我想在SQLAlchemy API中使用它,但无法使它正常工作。

编辑

我的最后工作结果:

代码语言:javascript
复制
episodes = Episode.query.filter(Episode.series_id.in_(x.id for x in g.user.favorite_series)).filter(Episode.air_time!=None).order_by(Episode.air_time)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-13 14:45:16

首先,你似乎没有宣布你的桌子的名字?此外,使用orm的主要目的是不必编写sql查询:

代码语言:javascript
复制
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import orm
import sqlalchemy as db
Base = declarative_base()

favorite_series = db.Table('favorite_series', Base.metadata,
    db.Column('user_id', db.Integer, db.ForeignKey('User.id')),
    db.Column('series_id', db.Integer, db.ForeignKey('Series.id'))
)
class Episode(Base):
    __tablename__ = 'Episode'
    id = db.Column(db.Integer, primary_key=True)
    season = db.Column(db.Integer)
    episode_num = db.Column(db.Integer)
    series_id = db.Column(db.Integer, db.ForeignKey('Series.id'))

    def __init__(self, season, episode_num, series_id):
        self.season = season
        self.episode_num = episode_num
        self.series_id = series_id

    def __repr__(self):
        return self.series.title + \
               ' S' + str(self.season) + \
               'E' + str(self.episode_num)

class Series(Base):
    __tablename__ = 'Series'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    episodes = orm.relationship('Episode', backref='series')

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

    def __repr__(self):
        return self.title

class User(Base):
    __tablename__ = 'User'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    favorite_series = orm.relationship('Series', 
        secondary=favorite_series, backref='users')

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

    def __repr__(self):
        return self.name

现在,您只需访问对象的属性,并让sql炼金术处理保持DB同步和发出查询的问题。

代码语言:javascript
复制
engine = db.create_engine('sqlite:///:memory:')
session = orm.sessionmaker(bind=engine)()
Base.metadata.create_all(engine)

lt = User('Ludovic Tiako')
the_wire = Series('The Wire')
friends = Series('Friends')
session.add_all([lt, the_wire, friends])
session.commit() # need to commit here to generate the id fields

tw_s01e01 = Episode(1,1,the_wire.id)
tw_s01e02 = Episode(1,2,the_wire.id)
f_s01e01 = Episode(1,1,friends.id)
f_s01e02 = Episode(1,2,friends.id)
f_s01e03 = Episode(1,3,friends.id)

session.add_all([tw_s01e01, tw_s01e02, 
                f_s01e01, f_s01e02, f_s01e03])
session.commit()


the_wire.episodes # > [The Wire S1E1, The Wire S1E2]
friends.episodes # > [Friends S1E1, Friends S1E2, Friends S1E3]

最后,回答你的问题:

代码语言:javascript
复制
lt.favorite_series.append(the_wire)
session.commit()
lt.favorite_series # > [The Wire]
[s.episodes for s in lt.favorite_series] # >> [[The Wire S1E1, The Wire S1E2]]
票数 5
EN

Stack Overflow用户

发布于 2012-05-12 11:23:49

我不知道如何使用Flask,但是从的文档来看,它似乎使用声明式,所以ORM。所以,你应该有个会议。我认为您可以从db.session访问它。

不管怎么说,如果这些假设是真的,你应该这样做:

代码语言:javascript
复制
query = db.session.query(User.id, Series.name, Episode.name).filter((Episode.series_id == Series.id) & \
    (User.id == favorite_series.c.user_id) & (Series.id == favorite_series.c.id) & \
    (User.id == 1))
results = query.all();

它可能不是您提供的确切查询,但应该这样做。

UPDATE:我刚刚检查了github上的Flask代码,看起来dbSQLAlchemy的一个实例,它有一个session属性,由返回会话对象的self.session = self.create_scoped_session(session_options)创建。所以这个应该能行。

而且,不是通过这样做,你就不会使用他们的BaseQuery,虽然我不知道这意味着什么.

检查文档,知道该做什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10562992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档