使用浮点数时,SQLAlchemy filter_by查询失败

时间:2019-09-17 11:36:51

标签: python postgresql sqlalchemy flask-sqlalchemy

我的模型定义如下:

class EnergyProfiles(db.Model):
    __tablename__ = "energy_profiles"
    id = db.Column(db.Integer, primary_key=True)
    device_id = db.Column(db.String(64), index=True, unique=False, nullable=False)
    device_hardware = db.Column(db.String(64), index=True, unique=False, nullable=False)
    location = db.Column(db.String(64), index=True, unique=False, nullable=False)
    time = db.Column(db.String(64), index=True, unique=False, nullable=False)
    accompanied = db.Column(db.Boolean)
    wellbeing = db.Column(db.String(64), index=True, unique=False, nullable=False)
    battery = db.Column(db.Integer, index=True, unique=False, nullable=False)

当我通过API添加新对象时,我想检查新对象(post_data)是否不存在。这项检查很容易

energy_profile_existing = EnergyProfiles.query.filter_by(**post_data).first()

但是,将battery列的类型从db.Integer更改为db.ARRAY(db.Float())后,前一个query.filter_by会失败,并显示一个postgres错误(忽略下面的user文本,这是docker撰写输出日志)

 operator does not exist: double precision[] = numeric[]
user_1           | LINE 3: WHERE energy_profiles.battery = ARRAY[0.1,20.1]
user_1           |                                       ^
user_1           | HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.

post_data包含battery作为JSON对象的一部分,例如

{
    "device_id": "CP99",
    "device_hardware": "Pycom",
    "location": "irregular",
    "time": "daytime",
    "accompanied": false,
    "wellbeing": "ok",
    "battery": [0.11, 35.22]
}

1 个答案:

答案 0 :(得分:1)

正如@benvc和@IljaEverilä指出的那样,当您传递不带任何非整数数值常量的显式转换的数组时,假定它们的类型为numeric

您可以做的是从cast the array's contentsfloat,可以使用array([])文字来声明数组,然后cast()ARRAY(Float)使用数据类型:

{
    "device_id": "CP99",
    "device_hardware": "Pycom",
    "location": "irregular",
    "time": "daytime",
    "accompanied": false,
    "wellbeing": "ok",
    "battery": cast(array([0.11, 35.22]), ARRAY(Float))
}