python - 试图跨多个表获取一组数据
问题描述
我正在尝试将两个表放在一起,以使用 flask-sqlalchemy 获取我需要的数据。Venue 表包含场地的城市和州,而 Show 表跟踪每个场地的表演。我需要查询按城市和州对场地进行分组,然后在该计数中计算 start_time 大于现在的节目数量。到目前为止,我所拥有的是:
query = db.session.query(Venue.city, Venue.state, Venue.name, Venue.id, Show.venue_id, Show.start_time).group_by(Venue.city)
但我不知道从那里去哪里,即使那是正确的起点。这些是我的模型:
class Venue(db.Model):
__tablename__ = 'venue'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String())
city = db.Column(db.String(120))
state = db.Column(db.String(120))
address = db.Column(db.String(120))
phone = db.Column(db.String(120))
image_link = db.Column(db.String(500))
facebook_link = db.Column(db.String(120))
seeking_talent = db.Column(db.Boolean, default=False)
seeking_description = db.Column(db.String())
genres = db.Column(db.ARRAY(db.String))
website = db.Column(db.String())
pastshows = db.relationship('Show', backref='pastshows', lazy=True)
class Show(db.Model):
__tablename__ = 'show'
id = db.Column(db.Integer, primary_key=True)
venue_id = db.Column(db.Integer, db.ForeignKey('venue.id'), nullable=False)
artist_id = db.Column(db.Integer, db.ForeignKey('artist.id'), nullable=False)
artist_name = db.Column(db.String())
venue_name = db.Column(db.String())
venue_image = db.Column(db.String())
start_time = db.Column(db.DateTime(), nullable=False)
这是我需要的数据:
data=[{
"city": "San Francisco",
"state": "CA",
"venues": [{
"id": 1,
"name": "The Musical Hop",
"num_upcoming_shows": 0,
}, {
"id": 3,
"name": "Park Square Live Music & Coffee",
"num_upcoming_shows": 1,
}]
}, {
"city": "New York",
"state": "NY",
"venues": [{
"id": 2,
"name": "The Dueling Pianos Bar",
"num_upcoming_shows": 0,
}]
}]
有人可以帮我解决这个问题吗?
解决方案
您需要使用.join(),它在两个表之间执行SQL JOIN - 如果不这样做,您将获得所谓的笛卡尔积。如果您有一个列表['a', 'b']
和[1, 2, 3]
,那么笛卡尔积就是['a1', 'a2', 'a3', 'b1', 'b2', 'b3']
,您可能会看到这很快就会失控。
无论如何,您要查找的代码与您所拥有的代码相似
query = db.session.query(
Venue.city,
Venue.state,
Venue.name,
Venue.id,
Show.venue_id,
Show.start_time
).select_from(Venue).join(
Show, Show.venue_id = Venue.id
).group_by(Venue.city)
我尽可能明确地写了几件事,但实际上可以简化:
.select_from
告诉你 FROM 子句,但如果省略,将采用第一个参数的表.query()
- 所以Venue
这里已经是默认值了。- 您已声明
pastshows
为一个relationship,这意味着 Flask-SQLAlchemy 应该知道如何链接这两个表。在这种情况下,您不必指定与 匹配的场所的 ID,而是venue_id
代码变为.join(Show)
,它使显式隐式。
因此,以下也应该起作用,但它隐式处理了更多的事情,因此具有更高的魔力。为了完整起见,我想添加它。
query = db.session.query(
Venue.city,
Venue.state,
Venue.name,
Venue.id,
Show.venue_id,
Show.start_time
).join(Show).group_by(Venue.city)