最近看了一下 SQLAlchemy 的文档, 感觉大致的使用方式跟 Django ORM 很像(包括 Peewee 之类都很像), 就是细节上感觉有点拧巴, 不如 Django 的 ORM 那么自然. 那 SQLAlchemy 相比有哪些优势呢? 谢谢大家.
1
changwei 2017-02-08 06:29:20 +08:00 via Android 2
我用过 php 下各种框架得 orm 之后觉得 python 下的 orm 都很拧巴。。。
|
2
bigzhu 2017-02-08 08:19:17 +08:00 via Android
早年没靠谱 orm 的时候(暴露年龄了),点了太多技能点在写 sql 上,之后觉得所有的 orm 都很拧巴。。。
|
3
chaleaoch 2017-02-08 08:40:11 +08:00
说几个 django orm 坑爹的地方。
1. 有些 group by 无法用 orm 实现。 2. 有些连表查询,用 djanog orm 写出来的 sql 是子查询。 3. 速度感人,一个两万条记录的查询,用时三秒。 sql<100ms 1 和 2sqlalchemy 有很好的解决方案。 3 我不确定 sqlalchemy 是更快还是更慢。 |
4
chaleaoch 2017-02-08 08:41:31 +08:00
还有 django orm 如法实现分表。至少原生不支持。只能分区。
sqlalchemy 支持。 |
7
chaleaoch 2017-02-08 08:54:45 +08:00
@XhstormR 该用 orm 还是得用 orm 毕竟方便。一直都用 sql 有两个问题,一个是预防 sql 注入,另一个是代码不易读。
|
8
precisi0nux 2017-02-08 09:25:35 +08:00 via iPhone
@changwei 毕竟是世界上最好的语言。
|
9
est 2017-02-08 09:27:14 +08:00 2
sqlalchemy 怎么评价呢,首先说,功能完善整齐
然后就是 1 楼所说的,拧巴!没错!有的时候真行想自己去撸 sql 。。 orm 是一种思维和开发的负担。难写难维护难调试 sqlalchemy 的问题,用一句话表示: from sqlalchemy.orm import joinedload, Load, load_only 你看,这里面包含了不含下划线全小写风格,驼峰风格,下划线风格三种 style 。真是玩死你系列。 |
10
TangMonk 2017-02-08 09:30:42 +08:00
ActiveRecord 路过。。
|
11
vicalloy 2017-02-08 09:52:17 +08:00
没用过 SQLAlchemy ,不是很了解。
很早之前简单的了解过 SQLAlchemy ,从 API 的友好度上看 Django 的 ORM 比 SQLAlchemy 好很多(个人看法)。 Django 的 ORM 调优其实并不是很难,很多时候慢是因为用的不对(糟糕的 SQL 一样慢)。 当然,在极少数情况下还是会出现 ORM 无能为力的情况,这时候可以直接写 SQL 。 ORM 和 SQL 并不冲突。为了这 0.x%的情况而放弃使用 ORM 很没必要。 @chaleaoch 1. Django 的查询可以嵌入 SQL ,也可以把自己手写的 SQL 绑定到对象上。 不知道你遇到的具体情况是怎么样的,不过在我看来第一条应当是可以实现。 2. 有些表连接写出来是子查询,这个需要结合具体案例,不是很确定是否是写法问题。 3. 2w 条数据查询用时 3 秒,这个非常不正常,需要结合具体代码进行分析。从我主观角度看是代码写的有问题。 |
12
zhouquanbest 2017-02-08 10:04:40 +08:00
以前只用 SQLAlchemy 现在用 Peewee 感觉 API 更友好
|
13
xiaket 2017-02-08 10:16:32 +08:00
我和你的感觉是一样的, Django 的 ORM 的易读性比 peewee 好一圈, peewee 的易读性比 SA 好两圈或更多...
|
14
est 2017-02-08 12:17:57 +08:00
@zhouquanbest peewee 坑多。主要与原因是 too young
@xiaket 赞同。 django 的 orm 其实挺好的。应付 90% 的逻辑没问题,读起来改起来都比 sql 容易太多。 |
15
anjianshi 2017-02-08 12:23:50 +08:00
sqlalchemy 硬着头皮用了一段时间,实在研究不下去,改用 peewee 了。
用 peewee ,哪里碰到了问题直接去查源码,主体就一个 python 文件,感觉代码思路很清晰,碰到的大部分问题都得以解决了。 用 sqlalchemy 的时候想查源码都查不出个头绪来 |
16
xiaket 2017-02-08 12:30:10 +08:00
@est 个人曾经想过把 Django 的 ORM 完全剥离出来,这样就可以脱离 Django 使用,后来看到 peewee 就放弃了... 不是说它做得有多好,不过至少是存在了.
|
17
loading 2017-02-08 12:37:02 +08:00 via Android
sqlalchemy 很多语言都有实现,换语言,换库都能直接上手。
|
19
chaleaoch 2017-02-08 13:15:09 +08:00
@vicalloy
@chaleaoch 1. Django 的查询可以嵌入 SQL ,也可以把自己手写的 SQL 绑定到对象上。 不知道你遇到的具体情况是怎么样的,不过在我看来第一条应当是可以实现。 ==== django orm 是有 extra 的写法,不过我把这种写法归于直接 sql 一类。(也是我个人观点) 2. 有些表连接写出来是子查询,这个需要结合具体案例,不是很确定是否是写法问题。 3. 2w 条数据查询用时 3 秒,这个非常不正常,需要结合具体代码进行分析。从我主观角度看是代码写的有问题。 ==== 非常简单 <model>.objects.all().values() 三秒 <model>.objects.filter(<这里假设出 10000 条数据>).values() 一秒 直接用客户端查询 select * from <table name> <100ms 我的理解问题出在 django orm 在生成映射结构的时候多处使用 for 循环导致的这个问题。 |
21
vicalloy 2017-02-08 14:03:23 +08:00 2
@chaleaoch
你可以再测试一下,<model>.objects.all().values() 绝对花不了 1 秒。 Django 的 QuerySet 是 Lazy 的,只有在你用的时候才会发生查询。 单纯执行上面的语句不会执行 SQL 。 如果你的写法是 >>> qs = <model>.objects.all().values() >>> list(qs) 超过 1s 是很正常的,因为你要把所有数据一次性取出来。你可以用调试工具看一下,生成的 SQL 就是`select * from <table name>`,查询速度本身是非常快的,但单 2w 条数据,别的不说,单网络传输都要费不少时间。 使用 Django 的 ORM ,如果慢的不正常,用调试工具看一下生成的 SQL ,通常都可以解决。所谓必须写 SQL 的地方极少。注: - 部分复杂报表,查询速度慢,用 ORM 性能优化有些难做。 - 需要用到数据库专有特性, Django 不支持,需要用 extra 内嵌少量 SQL 。 |
22
Jordan 2017-02-08 14:03:36 +08:00 via Android
SA 不适合初学者,以及一直用一种数据库的开发者。要驾驭好必须对 rmdb 有一定程度的认识,为了在不同数据库间充分利用他们的特性,并提供一致的接口, SA 没少下功夫,所以代码比其他 ORM 难读。 SA 不仅仅是 ORM 。
|
23
wangfengmadking 2017-02-08 14:35:01 +08:00
我只想说 SQLAlchemy 生成真正的 SQL 语句那就是灾难,性能的坑太多了。。。我觉得还是自己撸个简单的 ORM 比较好,我最新的项目就是这么干的, sql 执行效率杠杠的
|
24
t0p10 2017-02-08 15:04:16 +08:00
直接手写 SQL 运行速度比 ORM 快很多
|
25
ManjusakaL 2017-02-08 15:16:41 +08:00
Django 的 ORM 事务和多库支持简直鸡肋。。。
|
26
chaleaoch 2017-02-08 15:20:55 +08:00
@vicalloy
对,是我没说清楚. 我就是这个意思 >>> qs = <model>.objects.all().values() >>> list(qs) 超过 1s 是很正常的,因为你要把所有数据一次性取出来。你可以用调试工具看一下,生成的 SQL 就是`select * from <table name>`,查询速度本身是非常快的,但单 2w 条数据,别的不说,单网络传输都要费不少时间。 你的意思是说,(超过 1s 是很正常的)这一秒钟时间并不是 orm 引起的? |
27
chaleaoch 2017-02-08 15:23:52 +08:00
@ManjusakaL 多库还行啊...用 db_router...
|
28
chaleaoch 2017-02-08 15:24:58 +08:00
|
29
vicalloy 2017-02-08 15:30:04 +08:00
@chaleaoch
对 1s 很正常,和 ORM 没关系。 如果有 100w 条数据,你 list(qs)就不是慢的问题,内存会直接爆掉。 你执行 SQL ,实际上只是拿到一个游标,并没有立即将所有数据全部取出来。 你的 list(qs)实际上是一次性将数据全部取出丢到 list 里,不慢才怪。 |
30
wizardforcel 2017-02-08 15:35:45 +08:00
我觉得任何 orm 都很拧巴。。
本来把多维数据放进二维的表就够受得了,完了之后各种 sql 查询特性还支持不齐。遇到一种新的子句就要看看文档怎么实现,不同框架还不一样,难受死了。 |
31
est 2017-02-08 16:00:19 +08:00
@sagaxu
pep 没问题,但是你写 orm 语句就蛋痛了。 还是 django 或者 peewee 那种链式调用写起来舒服。 sqlalchemy 的 .option() 各种复杂结构,各种 func 太复杂了。不值得花那么多精力去抽象。 orm 本来就一种 dsl 了, sqlalchemy 是 dsl 里再发明一个 dsl 。 比如 primaryjoin="and_(xxx=yyy)" 这种简直丑得不要不要的。 |
32
chaleaoch 2017-02-08 16:14:54 +08:00
@vicalloy
部分认同你的观点: import MySQLdb # Open database connection db = MySQLdb.connect(<略>) import time starttime = time.time() sql0 = "select * from <略>" cursor = db.cursor(MySQLdb.cursors.DictCursor) cursor.execute(sql0) custom_html_data = cursor.fetchall() print time.time() - starttime cursor.close() 我这边输出的结果在 1.6 ~ 1.7 秒之间. 吃掉的那 1.3 秒就是 orm 的损耗. 这里有一个不严谨的地方就是,我没有测试当前时间点 django orm 的效率. 最后还有一个问题,如果这种时间的损耗都可以忽略的话,大家所说的 ORM 影响效率的点在哪里呢? |
33
sagaxu 2017-02-08 20:04:52 +08:00
@est 那是因为 SA 支持的 DB 种类更多,而且把 ORM 和 Expression 分别抽象再组合,有时可以只用 Expression ,能力上 SA 比 Django 更为全面和强大
|
34
lightening 2017-02-08 20:10:20 +08:00 via iPhone
看了以上评论觉得果然还是 ruby 的 ActiveRecord 好用啊!
|
35
ashin 2017-02-08 20:45:35 +08:00
肤浅的认为 sqlalchemy 并没有 django 的 orm 好,是真的好难用啊,文档也乱七八糟的感觉,每次都得去看源码,有人用估计也是在不用 django 的时候 orm 方案上早期没有太多的选择,看了 peewee 的文档后觉得 peewee 的文档结构够清楚,明确的要求 connect 和 close ,很方便就实现了自动 reconnect ,轻松两行代码就可以做到主从的读写分离,用 pwiz 还可以把已有的表自省生成 model ,感觉使用 peewee 才是 python orm 正确的选择,还有 records 也不错的样子,暂时还没有在项目里用过,说的是 SQL for Humans :)
|
36
param 2017-02-08 22:23:24 +08:00 via Android
有没有人告诉我,什么是拧巴
|
37
eyp82 OP 看到楼上有人说 SQLAlchemy 支持的 DB 更多, 先假定这是对的. 但感觉并没什么用啊. 一般应用数据库选型定了一种后很少会换, 支持主流的 MySQL, PostgreSQL, Oracle 就可以了吧, 再多也没什么用.
|
38
zeroten 2017-02-08 22:39:13 +08:00
哈,原来 peewee 用户挺多的
|
39
PythonAnswer 2017-02-08 22:41:42 +08:00 via Android
records 是基于 sqlalchemy 的
|
40
Gem 2017-02-08 22:59:54 +08:00
Python 里的 AR 实现: https://orator-orm.com/
|
41
ratazzi 2017-02-09 09:01:28 +08:00
还是 SQLAlchemy 功能完善,即使只是拼 SQL ,比如
sa.func.date(Model.c.created_at.op('AT TIME ZONE')(tz)) 一些较新的特性,比如 hstore 、 json 之类也是 SQLAlchemy 支持好 |
42
Panmax 2017-02-09 09:03:46 +08:00
|
43
chaleaoch 2017-02-09 09:24:48 +08:00
@Panmax 我也不会,只是又一次参加 pycon 年会的时候 达达的 rest api 负责人在做分享的时候讲到过.
你可以搜搜 2016 python 上海 网上能找到视频和 ppt 以及 github. |
44
findex 2017-02-09 17:37:34 +08:00
@bigzhu 我自己写了 ORM 后,觉得不如 SQLAlchemy 功能多,于是我就用 sqla 了。但是 sqla 比我自己写的 orm 臃肿。谁让它功能多呢?
还有我要说说,很多游戏开发里面都用到了类似于 SQL ORM 的思想。什么 post connect, reconnect, 之类的都有。 我觉得, ORM 在于思想问题。 django 自带的 ORM 跟 django 本身镶嵌太密切了,定制性能不好。当然如果你是 rich 的人,全上 django ,多花钱整机器也行。可以参考 instagram 。 sqla 的案例就更多了,什么 reddit , yelp 等等。 要记得,优化好了的 ORM 总是不如优化好了的 SQL 纯净语句。我曾经为了这个动了些脑筋。 |
45
findex 2017-02-09 17:40:41 +08:00
@est Python 就应该统一起来。驼峰风格学习下 Java 什么的语言。这样大家都能迅速读懂。
可惜 python 的很多库写手,也许喝了瓶酒,写库的时候,命名非常不规范,反正发布了,能 work 就行。但是如果是大公司发布标准库的话,应该注意很多。 当然当年的 MS 的很多库命名也十分令人蛋疼。 |
47
wizardforcel 2017-02-09 22:45:30 +08:00 via Android
你们好像忽略了 java 上的 orm 。。基本都得手写 sql ,也就是查询结果能映射一下。
优点是数据库特性支持的很好(废话),缺点是需要较高的 sql 功底。 |
48
songdezu 2017-02-14 00:25:59 +08:00
我有个问题 大家看看对不对:
用 orm 的主要优势是能保证各中平台 python javascript 的语法一致性, 不用学习不同 lib 比如 pymongo mongoose 的不同 api |
49
param 2018-05-19 10:36:05 +08:00
peewee 最大的问题在于没有好的 migration
|
51
param 2018-05-19 10:43:34 +08:00
咦。。。发现自己一年多之前居然回复过这个帖。。
|
54
thinker3 2018-09-15 09:26:49 +08:00
@firejoke 我写过,settings.py 只需要 DATABASES、INSTALLED_APPS 等关键的定义就可以了
|