我正在使用带有MySQL数据库的SQLAlchemy,我想计算表中的行数(大约300k).SQLAlchemy 计数函数的运行时间大约是在MySQL中直接写入相同查询的50倍.难道我做错了什么?
# this takes over 3 seconds to return
session.query(Segment).count()
Run Code Online (Sandbox Code Playgroud)
然而:
SELECT COUNT(*) FROM segments;
+----------+
| COUNT(*) |
+----------+
| 281992 |
+----------+
1 row in set (0.07 sec)
Run Code Online (Sandbox Code Playgroud)
速度的差异随着桌子的大小而增加(在100k行下几乎不可察觉).
更新
使用session.query(Segment.id).count()而不是session.query(Segment).count()似乎做的伎俩,让它加快速度.我仍然感到困惑,为什么初始查询速度较慢.
我正在寻找一种使用SQLAlchemy动态构造过滤器的方法.也就是说,给定列,运算符名称和比较值,构造相应的过滤器.
我将尝试使用示例进行说明(这将用于构建API).假设我们有以下型号:
class Cat(Model):
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
Run Code Online (Sandbox Code Playgroud)
我想将查询映射到过滤器.例如,
/cats?filter=age;eq;3 应该生成 Cat.query.filter(Cat.age == 3)
/cats?filter=age;in;5,6,7&filter=id;ge;10 应该生成 Cat.query.filter(Cat.age.in_([5, 6, 7])).filter(Cat.id >= 10)
我环顾四周看看它是如何完成的,但找不到一种方法,不涉及手动将每个操作符名称映射到比较器或类似的东西.例如,Flask-Restless保存所有支持操作的字典并存储相应的lambda函数(此处为代码).
我在SQLAlchemy文档中搜索并发现了两个潜在的潜在客户,但似乎都不满意:
使用Column.like,Column.in_...:这些运营商都可以直接在列这将使其简单的使用getattr,但一些人仍下落不明(==,>,等).
使用Column.op:例如,Cat.name.op('=')('Hobbes')但这似乎并不适用于所有运营商(in即).
有没有lambda功能的干净方法吗?