用了一段时间的 SQLAlchemy,感受到的只有混沌和混乱

2021-12-07 04:45:57 +08:00
 Richard14

作为一个初学者,最近带着学习的目的用了一段时间,因为我本人水平比较菜,本文无意对 sqlalchemy 提出任何批评,只是描述一些我使用中遇到的问题。

我没有什么 orm 使用经验,因为我司涉及的业务往往是大连表复杂查询,感觉 orm 不能带来多大的节省脑力的优势。平常我们业务中使用数据库,脱离开增删改查之外,更多的脑细胞应该是耗费在数据库储存原理上,如何规划数据和优化性能本身,虽然这部分花费的时间应该是最少。我从未想到有一天自己能在增删改查上耗费这么多的精力。

SQLAlchemy 在我这个初学者看来有若干明显问题,其中主要的就是设计上的混乱。随着新版本更新后,sqlalchemy 的世界(按我的划分),应该有三种分类方法,他们分别是

  1. ORM 和原生的区别。一个 orm 同时支持原生 sql 语言完全可以理解,支持原生混用也还可以接受,但是再复杂呢?
  2. 同步和异步的差异。2022 年已经快到了,使用异步代码访问数据库完全不是什么行为艺术,而是非常正当和迫切的需求。
  3. 1.0 和 2.0 风格的差别。据我观察它写的不是那么好的文档,sqlalchemy 有过一次语法设计上的大升级。

这三者组合之下就形成了 8 种搭配。从同步的->原生的->1.0 风格的代码,到异步的->ORM 的->2.0 式的调用,不一而足。在学习过程中文档本身就没有避免这种混乱,而有任何问题搜寻网络资料的话就更不一而足了。由于这是一个跨时间很长的项目,历史资料往往不能起到帮助,有时甚至会起到误导作用。而且作为 2022 年的项目,自然要尽可能地保证设计风格统一,就算网上找来一段代码可以 work ,如果它来自于不同的设计思路,融合进项目真的是好主意吗?

根据我的观察,ORM 还是很有必要的东西,包括虚拟的连接层,实际上起到的是数据库本身的内存优化的作用。在需要频繁读写业务数据的时候除了降低程序员心智开销,另一方面也能实打实地提高负载能力。但是我真的想吐槽这两天在网上找到的混乱的资料,还有让人一眼读不懂的文档,以及迁移到异步只给了一篇寥寥的说明,让我完全无法 get 到它的设计精神,以至于很多问题不能通过直觉解决,而网上的资料又全部过期。。

另外还有就是我作为初学者对于 ORM 的数据同步真的很疑惑,按照它的设计我无法理解数据同步是在哪里发生的,什么时候显式地发生,什么时候又隐式地发生,我在多端同时操作时什么时候需要注意脏读脏写问题。。。

总之我无意批评 sqlalchemy ,我知道所有的问题都是因为我太菜了,人家肯定有解决方案。但是用的这几天感觉是真的头大。。

5690 次点击
所在节点    Python
42 条回复
xhinliang
2021-12-07 11:43:43 +08:00
确实很恶心,给初学者带来了极大的不便。
adoal
2021-12-07 11:44:44 +08:00
@ospider LDAP……是想说 OLAP 吧
zhuangzhuang1988
2021-12-07 12:14:56 +08:00
同。
SmiteChow
2021-12-07 14:28:19 +08:00
那是你没掌握到 sqlalchemy 的精髓,如同元编程。
jakehu
2021-12-07 15:07:40 +08:00
只用 Core 部分功能,还挺好的
jiezhi
2021-12-07 15:12:02 +08:00
只想说 py 每次配置 MySQL 的驱动都是一头脑。。。 装了一堆,最后也不知道是哪个能用了
cclin
2021-12-07 15:14:03 +08:00
@adoal
```
{
"code":0,
"data":[
{
"nature":"nt",
"word":"大连表"
},
{
"nature":"ad",
"word":"复杂"
},
{
"nature":"v",
"word":"查询"
}
]
}
```
hanlp yyds
nikan999
2021-12-07 15:15:41 +08:00
@SmiteChow 能分享下 sqlalchemy 的精髓吗? 我用过 django sqlalchemy peewee, sqlalchemy 的学习曲线是最高的,但是带给我的收益不是很大,更多时候我需要一个连接池+ 快速上手的 crud
jjx
2021-12-07 15:24:44 +08:00
这段感觉已经回复过 n 次了一样

sqlalchemy 的两个层次, orm, sql expression

如果要可控性,建议只使用 sql expression

sql expression 让你用 python 写 sql , 个中体验,得深入了解才行

开发 erp 或企业软件的, 别说手写 sql! 一个复杂的 erp 报表可能几百行, 用 sql 的维护那个心酸

如果你灵活用 sqlalchemy 的 sql expression 重写, 直接代码降 n 倍而且重用
ipwx
2021-12-07 15:26:38 +08:00
@nikan999 简单的 ORM 不妨试试这个 https://sqlmodel.tiangolo.com/

对 SQLAlchemy 的二次包装
ipwx
2021-12-07 15:27:20 +08:00
@nikan999 SQLAlchemy 最大的吸引力是,随便切换 Backend 基本改改都能整个跑通。

不像裸 SQL 那换后端就是大工程。
nikan999
2021-12-07 15:44:29 +08:00
@ipwx 这个有听过 ,fastapi 作者写的, 还有一个是 records https://github.com/kennethreitz/records 也是基于 SQLAlchemy
以前 python 有项目需要支持各数据库的时候 也用的是 SQLAlchemy
但是我再去翻 SQLAlchemy 文档,还是感觉很难一下子就找到我需要的一些东西
nikan999
2021-12-07 15:49:17 +08:00
@ipwx 比如我需要 quickstart 和 FAQ 只需要 3-4 页的基本示例就能让项目快速跑起来,其它项目基本都有,然而 SQLAlchemy 的文档就是像字典一样,要去仔细查找,engine, session ,core,orm, 如果是用 flask-SQLAlchemy 和各种基于他的库帮忙简化开发还好,但是对于一个刚接触 ORM 的人来说,这个库的曲线在我看来有点过于高了
tabris17
2021-12-07 15:50:12 +08:00
人生苦短,我用 peewee
zachlhb
2021-12-07 17:17:26 +08:00
不得不说还是 Django orm 好用,最近还在研究 Django3 的异步,感觉 Django 足够用了
Richard14
2021-12-07 17:31:32 +08:00
@ospider py 的异步从 3.4 加入一直更到 3.7 已经有比较稳定的 api ,文档也从最初的大杂烩到现在的条理分明,覆盖全面,反观 sqlalchemy 直接一篇不算很长的“从 1.0 迁移到 2.0”,另一篇“sqlalchemy 与 asyncio”,说明含糊不清,覆盖单一,查看附录里的范例代码发现已经在正文中看过了。混乱的就是 sqlalchmy 本身,关 python 什么锅?

@Huelse 单纯用 orm 维护连接池有什么优势?我感觉用 core 库的连接池也一样啊
Richard14
2021-12-07 17:37:46 +08:00
@sagaxu 简单场景下性能肯定是提高的,我看他相当于把空间复杂度提上去了,比如一个实际业务中经常有各种恶心复杂的判定,搜索一行的 a 项目,如果 a>0 则 b 项目+=1 ,如果 b 项目+=1 结束后是偶数则 c 项目=0 ,这样一连串逻辑用普通 sql+连接池实现可能需要搜索和提交多次,我看他虚拟一层之后只需要在内存内部维护,实际业务发起多次请求,它往后端的搜索和提交只有几次,大部分在内存里完成,当然性能会比入库高。只不过这也是我无法理解的一点,我无法理解当问题变成多节点以后它维护的这个虚拟层是如何保持数据同步的
sagaxu
2021-12-07 18:54:46 +08:00
@Richard14 一般 orm 有工作 cache ,读是从 cache 里读,写入也是写入到 cache ,多次读和多次写可能会合并。这种功能你自己写也没几行代码的,但他自动做的未必是你期望的,如果不是非常熟悉,遇到问题根本没法排查。
wffnone
2021-12-07 19:13:38 +08:00
怎么说呢,我点进来是以为多少能看到一点稍微有一点价值的批评。

我不想讨论技术。楼主说,「作为一个初学者」,「因为我太菜了」。你真的把自己当初学者了吗,真的觉得自己菜吗?

这种标题,一般都是初级程序员会点进来。初级程序员交流技术,请不要交流看法,只说用法和事实就好了。
neoblackcap
2021-12-07 19:35:56 +08:00
data mapper 跟 active records 是两种 orm 的设计思路。没有优劣,只有合适跟不合适。

很多时候人家不做的功能不一定是他们懒,是有些功能本来就是几行代码的事情,库留给你自己实现。而不是强迫你接受它的实现。比如异步。
sqlalchemy 很多功能依赖于底层同步的数据驱动,上层如果硬是要全盘走异步。那么就是需要 sqlalchemy 帮你维护线程池。但是库并不是专为你服务的,还有很多项目是不需要异步功能的。所以它留给你自己选择。而不是出厂自带。毕竟用不了几行代码封装。

至于说自己 sql 写得好的,我见了很多其实都是“我会写 SQL”的水平,所以不要觉得自己写 sql 玩爆这些 orm 框架。当你要有一些变化的操作,你 sql 就很容易拼接起来,你真的能保证你的 sql 拼接处于一个很高的水平?这个时候也许你就走在写一个坡脚的 sql builder 或者 orm 框架的路上了。

觉得有问题,可以多去了解项目的变迁。如果你觉得我就是一个 curd boy ,不需要了解这些工具的历史。那么我只想说你自求多福吧。或者这些工具从一开始就不适合你用。也许其他的会更好。或者你也可以自己重新写一个。
计算机领域没有什么永恒的,有 apache web server ,也会有 nginx 。有 memcache ,也会有人去写 redis 。只不过很多人并不是写出一个更好的罢了。所以了解历史,从中汲取经验,避免掉坑也是一件好事。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/820498

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX