总结一下这个问题,我无法使用SQLAlchemy针对浮点值选择任何实体。
例如:
m = session.query(Model).get(1);
all_m = session.query(Model).filter(Model.some_float_value, m.some_float_value)
all_m是空的,而我希望它总是至少有一个!
如何在SQLAlchemy中基于任意精度过滤浮点值(EG。我可能希望匹配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不是很熟悉,并且无法找到有关如何创建自定义比较函数的文档,或者找不到我需要的任何内置函数。
是否有可以使用的内置函数,为过滤器方法提供自定义比较函数的方法,还是我为此编写原始查询/过程?
有条件的信息:
Postgres 9.2
SQLAlchemy 0.9
值存储为双精度浮点
所有模型都是这样定义的(有很多模型,这使得显式列定义的解决方案不太理想):
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)
修改的
为了清晰起见,我完全重写了我的问题。对不起,我很难与人交流......
答案 0 :(得分:1)
自定义比较的一个具体示例显示在GeoAlchemy中(尽管对于您的应用程序可能有点过分)。虽然下面链接中的示例使用边界框来比较空间坐标,但您可以使用更简单的方法在容差范围内实现比较。
例如,参见Comparator类,它定义"〜="和其他运营商:
http://geoalchemy-2.readthedocs.org/en/0.2.4/spatial_operators.html
由于您提到您无法找到有关如何实现自定义比较功能的文档,请参阅此处:
http://docs.sqlalchemy.org/en/latest/core/types.html#types-operators
在相关说明中 - 如果要防止在浮点列保持在某个阈值内时触发数据库更新,请参阅此处的讨论:
https://groups.google.com/forum/#!msg/sqlalchemy/tCpsGZmjk_w/lOwW93qHV0sJ
(免责声明:这是基于谷歌搜索,我是SQLAlchemy的新手)
答案 1 :(得分:0)
浮点数的一个经验法则是"从不比较浮点数是否相等。" (谷歌可以引用。)
最简单,最可预测的方法是使用SQL十进制(n,m)数据类型而不是float。 SQL十进制(n,m)数据类型没有近似误差。
SQLAlchemy supports SQL decimals
如果你必须使用双打,你最好的选择可能是遵循C FAQ推荐的两种方法之一。
计算不等式(abs(a-b) >= 0.01)
的一个问题是,结果将使用与a
和b
最接近的浮点近似值计算得出。那些浮点近似值可能正是您期望它们的值,但这取决于应用程序。 (十进制值45.06和45.062不是您所期望的那样,当它们被分配给一个双精度时。换句话说,最接近45.06的浮点近似值不是45.06。)
C FAQ对于使用这种表达方式作为确定平等的通用方法有所说明。