Python 在SQLAlchemy中查询浮点值

Python 在SQLAlchemy中查询浮点值,python,floating-point,sqlalchemy,Python,Floating Point,Sqlalchemy,总而言之,我不能使用SQLAlchemy针对浮点值选择任何实体 例如: m = session.query(Model).get(1); all_m = session.query(Model).filter(Model.some_float_value, m.some_float_value) 所有的m都是空的,而我希望它总是至少有一个 如何基于任意精度过滤SQLAlchemy中的浮点值(例如,某些我可能希望匹配到0.01或其他我可能以0.0005的精度过滤) 例如,我希望能够编写一个通用函

总而言之,我不能使用SQLAlchemy针对浮点值选择任何实体

例如:

m = session.query(Model).get(1);
all_m = session.query(Model).filter(Model.some_float_value, m.some_float_value)
所有的m都是空的,而我希望它总是至少有一个

如何基于任意精度过滤SQLAlchemy中的浮点值(例如,某些我可能希望匹配到0.01或其他我可能以0.0005的精度过滤)

例如,我希望能够编写一个通用函数,以便在代码中编写如下查询:

session.query(Model)\
    .filter(Model.foo == "bar",
            match_float(Model.some_float_value, float_val, 0.025)).all()
若存在与0.025近似公差范围内的任何内容相匹配的公差

然而,我对SQLAlchemy不是很熟悉,并且无法找到关于如何创建自定义比较函数的文档,或者任何可以实现我所需功能的内置函数

我是否可以使用内置函数,是否可以为filter方法提供自定义比较函数,或者是否可以为此编写原始查询/过程

传统信息:

博士后9.2

SQLAlchemy 0.9

值存储为双精度浮点

所有模型都是这样定义的(有很多模型,这使得使用显式列定义的解决方案不太理想):

编辑


为了清楚起见,我完全改写了我的问题。很抱歉造成混淆,我无法与人交流…

浮点数的经验法则之一是“永远不要比较浮点数是否相等。”(你可以在谷歌上找到这句话。)

最简单和最可预测的方法是使用SQL decimal(n,m)数据类型而不是浮点。SQL十进制(n,m)数据类型没有近似错误

如果您必须使用双打,您最好的选择可能是遵循

计算不等式
(abs(a-b)>=0.01)
的一个问题是,将使用最接近
a
b
的浮点近似值来计算结果。这些浮点近似值可能正是您期望的值,但这取决于应用程序。(将十进制值45.06和45.062指定给double时,它们不是您期望的值。换句话说,与45.06最接近的浮点近似值不是45.06。)


C FAQ中有一些关于使用这种表达式作为确定相等性的通用方法的说明。

一个用于自定义比较的具体示例显示在GeoAlchemy中(尽管对于您的应用程序来说可能有些过分)。虽然下面链接中的示例使用边界框来比较空间坐标,但可以使用更简单的方法在公差范围内实现比较

例如,请参见此处定义“~=”和其他运算符的Comparator类:

由于您提到无法找到有关如何实现自定义比较函数的文档,请参见此处:

请注意—如果要防止在浮点列保持在某个阈值内时触发数据库更新,请参阅此处的讨论:


(免责声明:这是基于谷歌搜索,我是SQLAlchemy新手)

对你来说“匹配到.01”意味着什么?它意味着匹配任何东西(abs(a-b)>=0.01),或者换句话说,它只能与45.06相比较。我能把所有这些都做好**我不知道如何编写一个函数,为过滤器函数中的参数返回有效的匹配条件**更准确地说,它可以精确地表示有限的小数。十进制在表示pi或1/3方面并不比二进制好。感谢您的回复,我需要在变量进动时匹配双值,而不是在固定进动时匹配十进制字段。你能提供一些关于我如何做到这一点的见解吗?@PatriciaShanahan这些值实际上是整数值的分数运算结果,因此你的评论非常相关。谢谢。@drkstr1:更新的答案。我很抱歉我的问题没有说得更清楚。我确切地知道浮点数是如何工作的。我需要知道如何在SQLAlchemy中查询它们。是否有一个内置函数可以使用,一种为filter方法提供自定义比较函数的方法,或者我是否需要为此使用原始查询?谢谢你的时间!谢谢你的回复。更改ORM不是一个选项,但如果没有更好的解决方案,我可能最终会接受您关于自定义类型运算符的建议,认为这不是一个理想的解决方案。模型数量众多,并且都有很多领域。如果没有自动生成的模式,维护和更新将非常困难。即使是注入原始查询的包装函数,如果它在我需要的任何字段上通用,也将是一个更好的解决方案。“即使是注入查询的包装函数也将是一个更好的解决方案…”的变体如何:我相信那里的第一条注释仍然需要自定义类型重写器。还有,你对超控有什么具体的想法?你的意思是我应该重写equals操作符并发送一个带有(值,精度)类型的touple吗?第二条评论有一个断开的链接。不确定链接发生了什么,这里又是:我的意思是:你能对查询进行子类化,添加一个新的方法吗?我不确定您仅限于哪些选项,因此我想强调添加全新方法的选项。我不认为这种方法需要自定义类型。
engine = create_engine('postgresql://user:pass@localhost:1234/database')
Base = declarative_base()
metadata = MetaData(bind=engine)

class Model(Base):
    __table__ = Table('model', metadata, autoload=True)