首页 > 解决方案 > SQLAlchemy 查询的最小值/最大值有限制

问题描述

大家好,

我有几个传感器读取温度和湿度。使用 SQLAlchemy,我成功查询了每个传感器的最后十个结果:

 sensorlist = db.session.query(Sensor).order_by(Sensor.id.asc()).all()
    for sensor in sensorlist:
        readings = sensor.readings.order_by(Sensorreading.time.desc()).limit(10)

现在我想要十个结果中的最小值和最大值,所以我可以展示每个传感器的结果。就像是:

<sensor 1, min temp = 23, max temp = 26, min hum = 56, max hum =74>
<sensor 2, min temp = 22, max temp = 30, min hum = 51, max hum =63>
<sensor 3, min temp = 24, max temp = 25, min hum = 62, max hum =75>

但我不知道如何用 SQLAlchemy/python 查询。对于我使用此代码进行的每次阅读,但我无法在计算最小值/最大值之前限制数据。如果我将 .all() 替换为 .limit(10),那么它只会查询十个传感器,而不是十个读数:

sensors = db.session.query(Sensor.name, db.func.min(Sensorreading.temp_value).label("temp_value_min"), db.func.max(Sensorreading.temp_value).label("temp_value_max")).outerjoin(Sensorreading, Sensor.id == Sensorreading.sensor_id).group_by(Sensor.name).all()

只是为了一些背景信息,我的桌子的模型:

class Sensor(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    sensor_type = db.Column(db.Integer)
    pin = db.Column(db.Integer)
    limit_temp_up = db.Column(db.Float)
    limit_temp_down = db.Column(db.Float)
    limit_hum_up = db.Column(db.Float)
    limit_hum_down = db.Column(db.Float)
    limit_aqua_temp_up = db.Column(db.Float)
    limit_aqua_temp_down = db.Column(db.Float)
    readings = db.relationship('Sensorreading', backref='sensor', lazy='dynamic')

class Sensorreading(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    time = db.Column(db.DateTime)
    name = db.Column(db.String(50))
    temp_value = db.Column(db.Float)
    hum_value = db.Column(db.Float)
    aqua_temp_value = db.Column(db.Float)
    sensor_id = db.Column(db.Integer, db.ForeignKey('sensor.id'))

希望有人可以提供帮助。欢迎任何提示、技巧、代码帮助或链接!提前致谢。

标签: pythonsqlalchemyflask-sqlalchemy

解决方案


我认为在这种情况下最好使用限制和偏移。如果您从 sql 中返回一个大数据集并在内存中对该集进行切片,这将导致一些不必要的开销。

此解决方案将返回一个包含 10 个项目的数据集(分页发生在 sql 端):

sensors = db.session.query(Sensor.name, db.func.min(Sensorreading.temp_value).label("temp_value_min"), db.func.max(Sensorreading.temp_value).label("temp_value_max")).outerjoin(Sensorreading, Sensor.id == Sensorreading.sensor_id).group_by(Sensor.name).limit(10).offset(0).all()

对于偏移量,您需要第一项 - 1。因此,第 1 页从第 1 项开始,您需要将偏移量设为 0。对于第 2 页,偏移量将为 11 - 1 = 10。


推荐阅读