CWYAlpha

Just another WordPress.com site

Thought this was cool: PonyORM – python的新一代黑魔法级别ORM

leave a comment »


简单的例子,来自官网

python的查询代码:

select(c for c in Customer
     if sum(c.orders.price) > 1000)

通过PonyORM翻译成SQL:

SELECT "c"."id"
FROM "Customer" "c"
  LEFT JOIN "Order" "order-1"
    ON "c"."id" = "order-1"."customer"
GROUP BY "c"."id"
HAVING coalesce(SUM("order-1"."total_price"), 0) > 1000

以前觉得peewee的查询语法很clever,比Django那种丑爆的 price__gt=1000 好出一条街。那么PonyORM就超出其他python ORM一条银河系了。

这个PonyORM的黑魔法在哪里呢?

  1. 首先select(x for x in ...) 这是一个generator comprehension,和list comprehension不同的是,返回的是一个惰性求值的生成器,于是
  2. 该表达式bytecode可以反编译
  3. 把Python的AST翻译成SQL的AST
  4. 分离和优化查询。
  5. 把SQL AST生成为特定数据库的query
  6. 执行SQL query
  7. 把返回构造成python对象,并且缓存。

出自PonyORM开发者 u/amalashkevich。更加详细的黑魔法解释可以在stackoverflow上看到。

可以说Peewee和PonyORM的设计才是优雅的。但是PonyORM更加高级,基本接近了LINQ和超过了Hibernate HQL。

顺便提一下,有一个另外类似的ORM——PQL,用于MongoDB:

比如:

pql.find("a > 1 and b == 'foo' or not c.d == False")

翻译成MongoDB的查询:

{'$or': [{'$and': [{'a': {'$gt': 1}}, {'b': 'foo'}]}, {'$not': {'c.d': False}}]}

很可惜它是基于字符串的翻译,而不是原生python表达式。

其他讨论

from est's blog: http://blog.est.im/post/49564925054

Written by cwyalpha

五月 4, 2013 在 4:53 上午

发表在 Uncategorized

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: