[英]Querying two tables using SQLAlchemy and PostgreSQL
I need help improving my SQLAlchemy query.我需要帮助改进我的 SQLAlchemy 查询。 I'm using Python 3.7, SQLAlchemy 1.3.15 and PosgresSQL 9.4.3 as database.
我正在使用 Python 3.7、SQLAlchemy 1.3.15 和 PosgresSQL 9.4.3 作为数据库。 I'm trying to return the count of appointments for a specific date and timeslot.
我正在尝试返回特定日期和时间段的约会计数。 However, my appointments and appointment slot tables are separate and I'm having to query both models/tables to get the desired results.
但是,我的约会和约会空档表是分开的,我必须同时查询模型/表才能获得所需的结果。 Here's what I have;
这就是我所拥有的;
Appointments Model约会 Model
The appointment table have a few columns, which includes a foreign key to the appointment slots table.约会表有几列,其中包括约会时隙表的外键。
class Appointment(ResourceMixin, db.Model):
__tablename__ = 'appointments'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id', onupdate='CASCADE', ondelete='CASCADE'), index=True, nullable=True)
slot_id = db.Column(db.Integer, db.ForeignKey('appointment_slots.id', onupdate='CASCADE', ondelete='CASCADE'), index=True, nullable=False)
appointment_date = db.Column(db.DateTime(), nullable=False)
appointment_type = db.Column(db.String(128), nullable=False, default='general')
Appointment Slots Table预约时段表
The appointment slots table contains the time slots for the appointments.约会时隙表包含约会的时隙。 The Model consist of a relationship back to the appointments table.
Model 包含与约会表的关系。
class AppointmentSlot(ResourceMixin, db.Model):
__tablename__ = 'appointment_slots'
id = db.Column(db.Integer, primary_key=True)
# Relationships.
appointments = db.relationship('Appointment', uselist=False,
backref='appointments', lazy='joined', passive_deletes=True)
start_time = db.Column(db.String(5), nullable=False, server_default='08:00')
end_time = db.Column(db.String(5), nullable=False, server_default='17:00')
SQLAlchemy Query SQLAlchemy查询
Currently I'm running the following SQLAlchemy query to get the appointment count for a specific date and time slot;目前我正在运行以下 SQLAlchemy 查询以获取特定日期和时间段的约会计数;
appointment_count = db.session.query(func.count(Appointment.id)).join(AppointmentSlot)\
.filter(and_(Appointment.appointment_date == date, AppointmentSlot.id == Appointment.id,
AppointmentSlot.start_time == time)).scalar()
The query above return the correct results, which is a single digit value, but I'm worried that the query is not optimized.上面的查询返回正确的结果,是个位数的值,但我担心查询没有优化。 Currently the query returns in
380ms
, but there's only 8 records in the appointments
and appointment_slots
tables.目前查询在
380ms
内返回,但在appointments
和appointment_slots
槽表中只有 8 条记录。 These tables will eventually have in the 100s of thousands of records.这些表最终将拥有成百上千条记录。 I'm worried that even though the query is working now that it will eventually struggle with an increase of records.
我担心即使查询现在正在工作,但它最终会因记录的增加而苦苦挣扎。
How can I improved or optimized this query to improve performance?如何改进或优化此查询以提高性能? I was looking at SQLAlchemy subqueries using the appointment relationship on the
appointment_slots
table, but was unable to get it to work and confirm the performance.我正在查看 SQLAlchemy 子查询,使用约会插槽表上的
appointment_slots
关系,但无法让它工作并确认性能。 I'm thinking there must be a better way to run this query especially using the appointments relationship
on the appointment_slots
table, but I'm currently stumped.我认为必须有更好的方法来运行此查询,特别是使用约会_slots 表上的
appointment_slots
appointments relationship
,但我目前很难过。 Any suggestions?有什么建议么?
I was incorrect about the query load time.我对查询加载时间不正确。 I was actually looking at the page load that was 380ms.
我实际上正在查看 380 毫秒的页面加载。 I also change the some fields on the models by removing the
slot_id
from the appointments
model and adding a appointment_id
foreign key to the appointment_slots
model.我还通过从
appointments
model 中删除slot_id
并将appointment_id
ID 外键添加到appointment_slots
model 中来更改模型上的某些字段。 The page load for the following query;以下查询的页面加载;
appointment_count = db.session.query(func.count(Appointment.id)).join(AppointmentSlot)\
.filter(and_(Appointment.appointment_date == date,
AppointmentSlot.appointment_id == Appointment.id, AppointmentSlot.start_time == time)).scalar()
ended up being;最终成为;
0.4637ms
. 0.4637ms
。
However, I still tried to improve the query and was able to do so by using a SQLAlchemy subquery.但是,我仍然尝试改进查询,并且能够通过使用 SQLAlchemy 子查询来做到这一点。 The following subquery;
以下子查询;
subquery = db.session.query(Appointment.id).filter(Appointment.appointment_date == date).subquery()
query = db.session.query(func.count(AppointmentSlot.id))\
.filter(and_(AppointmentSlot.appointment_id.in_(subquery),
AppointmentSlot.start_time == time)).scalar()
Return a load time of 0.3700ms
which shows a much better performance than using the join query.返回
0.3700ms
的加载时间,这显示出比使用连接查询更好的性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.