【发布时间】:2013-04-13 12:02:24
【问题描述】:
Pony ORM 很好地将生成器表达式转换为 SQL。示例:
>>> select(p for p in Person if p.name.startswith('Paul'))
.order_by(Person.name)[:2]
SELECT "p"."id", "p"."name", "p"."age"
FROM "Person" "p"
WHERE "p"."name" LIKE "Paul%"
ORDER BY "p"."name"
LIMIT 2
[Person[3], Person[1]]
>>>
我知道 Python 具有出色的内省和元编程内置功能,但是这个库如何能够在不进行预处理的情况下翻译生成器表达式?看起来很神奇。
[更新]
搅拌机写道:
Here is the file 你所追求的。它似乎使用一些自省魔法来重建生成器。我不确定它是否支持 100% 的 Python 语法,但这很酷。 – 搅拌机
我以为他们正在探索生成器表达式协议的某些功能,但是查看此文件,并看到涉及的 ast 模块...不,他们不是在动态检查程序源,是吗?令人兴奋...
@BrenBarn:如果我尝试在select函数调用之外调用生成器,结果是:
>>> x = (p for p in Person if p.age > 20)
>>> x.next()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "<interactive input>", line 1, in <genexpr>
File "C:\Python27\lib\site-packages\pony\orm\core.py", line 1822, in next
% self.entity.__name__)
File "C:\Python27\lib\site-packages\pony\utils.py", line 92, in throw
raise exc
TypeError: Use select(...) function or Person.select(...) method for iteration
>>>
似乎他们正在执行更多神秘的咒语,例如检查 select 函数调用和动态处理 Python 抽象语法语法树。
我还是希望有人解释一下,来源远远超出了我的魔法水平。
【问题讨论】:
-
推测
p对象是 Pony 实现的类型的对象,它查看正在访问的方法/属性(例如,name、startswith)并将它们转换为SQL。 -
Here 是您需要的文件。它似乎使用一些自省魔法来重建生成器。我不确定它是否支持 100% 的 Python 语法,但这很酷。
-
@Blender:我在 LISP 中看到过这种技巧 - 在 Python 中实现这种特技简直是病态!
标签: python orm metaprogramming dsl ponyorm