兄弟们,prisma 有坑,快跑♀
https://github.com/prisma/prisma/issues/101421
https://github.com/prisma/prisma/issues/10142#issuecomment-1835279273
https://github.com/prisma/prisma/issues/20128
时区的问题,对于查询,写入,始终以 UTC 时区,从而忽略了 db 本身的时区,且 client 无法调整 https://github.com/prisma/prisma/issues/5051
model 中的关联关系对于业务侧使用显得特别笨重,比如简单的连表查询,尤其是那种不同业务需要临时或一次性的连表查询需要 Prisma.sql 来进行,如果在复杂则要走 typedsql;但是 typedsql 不支持动态条件,这种场景是业务侧最最最最多的,因此即便就是简单的列表+总条数查询都需要结合 Prisma.sql 来做原生 SQL 的拼接。
在遇到上面 1,2 的时候硬着头皮继续,但是遇到 3 的时候彻底让我放弃了它。
提桶跑路了 ♀
兄弟们,节约时间,原理 prisma
![]() | 1 subframe75361 147 天前 via Android 试试 kysely ,sql 的写法。或者用更火但 dx 差一些的 drizzle orm |
2 yaodong0126 147 天前 你还真别说,迷信 prisma 的人多的一腿 |
![]() | 3 ultimate42 147 天前 我是从 typeorm 转到 prisma 的,prisma 确实有不少痛点,时区,联表查嵌套层级深什么的,但感觉开发体验上,prisma 还是要好一点 |
![]() | 同样 delete 一个不存在的数据也会报错,官方解决方案说是用 executeRaw.. |
![]() | 5 qiubaowei 147 天前 还好我是守旧派 一直用 sequelize |
![]() | 6 flyingcrp OP @ultimate42 我试了,确实不行。model 中注释都不支持。感觉还是差点意思 |
7 flmn 147 天前 drizzle 比较好 |
![]() | 8 BeautifulSoap 147 天前 也借地方顺便也让大家避坑一个 ORM:千万不要用 drizzle ,千万不要用 drizzle ,千万不要用 drizzle |
![]() | 9 Hbisedm 147 天前 drizzle |
![]() | 10 asen001 147 天前 @BeautifulSoap drizzle 有什么坑,有个私活项目用 drizzle 开发到一半了,别吓我 |
![]() | 11 SolidZORO 147 天前 说一个小众 ORM https://sutando.org/ ,底层是 knex ,进可 ORM ,退可 knex RAW 。 之所以是说而不是推荐,因为实在太小众,推荐的话实在担不起这个责任,只想让更多人知道它。sutando 作者维护不算积极,total 就两人维护,start 几十,但是手感是我用过所有 ORM 里面最好的,基本上做到了 1:1 对标 Laravel 的 Eloquent ,用起来及其优雅。比堪称是 nodejs 届 Laravel 的 adonisjs 自带强耦合的 lucid 还要想像 Eloquent 。 y1s1 Node 这边的 ORM 真是烂得可以。drizzle 烂。Prisma 烂,typeORM 烂中烂。 唯一能打一下的是 sequelize ,的确是可靠了,但是及其嗦,TS 支持太差(我是说第三方,第一份约等于没有),以及无止境的 beta 让人又爱又恨。 |
![]() | 12 yandif 147 天前 @BeautifulSoap 同问有啥坑? |
![]() | 13 BeautifulSoap 147 天前 @asen001 真用了那就用嘛,也不是不能用,反正之前写 drizzle 我是真的火大 官方文档写得一塌糊涂,看起来很正规但有用的信息基本没多少 schema 一堆特性不支持,连最基本的 index desc asc, union index 都不支。到最后不光要写 schema 还要自己去写额外的 migration sql 类型检查基于 schema 定义,如果我 select 的字段里掺杂了动态生成自动的内容(比如 COUNT(*)之类)的话,过类型检查能折腾死人 执行 raw sql 并且获取到返回值而且要过类型检查比登天都难 等等等等,反正下次项目里谁跟我说用 drizzle 我跟谁急 |
![]() | 14 12tall 147 天前 knex 应该是用的最舒服的了,虽然只是一个 builder |
![]() | 15 shakaraka PRO drizzle +1 |
![]() | 16 flyingcrp OP 目前应该是在 typeorm 中暂时不打算出去了。 prisma 在构建和打包时也会有很多问题。不设置 binary 的话会直接多 30M+的大小。很离谱。 然后里面还有一个奇怪的地方,当前 prisma 已经让用自定义 output 路径去做 client 的引入。 但是底层似乎有依赖了 prisma ,这个里面有个 public 文件夹,里面全是一些文档还是啥的。也是三十多 M. |
17 justdoit123 147 天前 也尝试使用 prisma ,说说我觉得的痛点与疑惑,希望有经验的解答下: 1. prisma 不生成 class ,如何进一步跟 class-validator 以及 swagger 结合? 2. 不生成 class ,如果我有很简单的 computed field ,就不知道怎么实现。虽然官方有 [Client extension]( https://www.prisma.io/docs/orm/prisma-client/queries/computed-fields#using-a-prisma-client-extension) 方案,但是 extend 后的 model 类型获取不直接。虽然可以通过类型体操获取。 3. 个人对滥用 DSL 很反感。DB 的 schema 真的到了需要叠一层 DSL 的程度了吗? 我个人认为还没必要,这样做的收益不高。为了“无缝”切换 DB 类型吗?正常项目开发不会频繁切换 DB 类型,况且也无法做到无缝。 想要降低使用 DB 的门槛吗?熟悉一个 DB 真的是后端的基础门槛,你虽然可以暂时欠着,但是终究要还上,借助 DSL 会很被动,学的都是人家嚼碎了喂你的东西。prisma 用 DSL 描述 schema 的理由,我能想到的唯一理由应该就是他们的野心是实现一个跨语言的 ORM 。 |
18 ByteCat 147 天前 在用 drizzle ,感觉很爽,可以写类似 sql 的语法,复杂查询很方便 |
![]() | 19 Hanggi 147 天前 ![]() 感觉楼主还是对 ts 的编程思想理解和 prisma 的使用方法上...有不一致吧。 技术选型按自身的理解和喜好来就可以了。 看看 prisma 自己对 typeorm 的对比,有没有吸引自己转战的特性, https://www.prisma.io/docs/orm/more/comparisons/prisma-and-typeorm 至少目前看来 prisma 是趋势,能早点上手就早收益,用不来也没必要强求,毕竟有那么多人还在宣扬不用 orm ,sql 就应该手写,hhh 。 https://npmtrends.com/prisma-vs-sequelize-vs-typeorm |
![]() | 20 Belmode 147 天前 我就觉得用 Prisma 能省点事,不用写一堆像 TypeOrm 中那样的实体对象,写很多注解 |
![]() | 22 cutchop 146 天前 typescript 挺好的,不知道为什么 prisma 要发明新的格式 |
23 rocmax 146 天前 via Android @BeautifulSoap 1. 文档的问题确实存在,过于简略,需要自己摸索 2.这些都支持啊,我一看还以为这是以前旧帖子呢。drizzle 基本就是把 ts 翻译成 sql ,这种一个关键字就解决的问题怎么会不支持。没有听说过 union index ,你是指复合索引吗,也支持的啊。union 操作倒是不支持是由于类型推断困难,不重视类型安全的可能会支持。 3. 类型检查当然要基于 schema 定义了,要不咋办? count (*)可以使用 sql<number>标注类型 4. 同上,你不给类型标注,数据库返回的是 text ,不得按类型 parse 吗。 |
24 rocmax 146 天前 via Android @cutchop 跟 drizzle 比起来 prisma 的 schema 确实简单好懂,我一个简单项目 drizzle schema 都快 1000 行了,除了我自己没人能看懂,估计也没人有耐心看完,幸好有 visualizer 。 |
25 rocmax 146 天前 via Android @justdoit123 是的,比如 golang: https://github.com/steebchen/prisma-client-go 由于 prisma core 从 rust 改回 ts ,被放弃了 |
26 rocmax 146 天前 @BeautifulSoap 对不起,上面说的有误,sql<T>`COUNT(*)`类型标注没有用,需要 mapWith 函数 |
![]() | 27 k9982874 146 天前 via iPad 用不上那些高大上的 orm 功能,转到了 postgres.is 楼上推荐的 Kysely ,感觉比较像 gorm ,有空试试 |
![]() | 28 BeautifulSoap 146 天前 @rocmax 2. 你自己试试看 mysql 的 schema 里能不能指定 asc 或者 desc 的 index 吧。postgresql 可以,但是 mysql 不行的。并且 mysql 的复合索引文档里根本找不到怎么用 4. 这个你自己亲自写一下就知道了。就最简单的用 drizzle 执行 mysql 的 `show tables` 然后解析出所有表格。保证你一写一个不吱声。官方文档里只写了怎么执行 raw sql 但对怎么获取到 raw sql 的返回值只字不提。最后花了 N 久时间才找到解决办法 |
29 rocmax 146 天前 @BeautifulSoap https://drizzle.run/nx1z72u347hvkyjd0zspe7ki 这样如何? 我司从去年初就全面改用 postgresql 了,确实我说的是 postgresql 的情况。 mysql 的时期用的是 prisma |
30 rocmax 146 天前 @BeautifulSoap 我知道为啥对 sql<T>类型标注产生错觉了,好像 COUNT 的返回值类型就是 number ,即便标注了 string 依旧是 number https://drizzle.run/lstx39x8scbt8gotd2ndrwhp |
![]() | 31 Trim21 146 天前 现在在用 drizzle ,但是感觉维护者对 mysql 相关的特性不太重视 ... |
![]() | 32 ratazzi 146 天前 正在用 prisma 看了这帖子怕了,typeorm 简单试过一下,看到生成的 SQL 之后果断放弃,现在我对 JS 写 CRUD 一点兴趣都没了 |
![]() | 33 flydogs 146 天前 via iPhone 三天时间不算浪费,至少你知道了不适合你现在这个项目。 |
![]() | 34 zieglar 146 天前 @justdoit123 #17 我的做法是新建一个 class 来继承 prisma 对应的实体 class ,在新建的自有 class 的基础上去做各种字段装饰、处理操作 |
![]() | 35 flyingcrp OP @Hanggi 我确实有可能没有完全理解 prisma 的设计思想。但在业务侧开发中我提到的那些问题,确实是实打实的极大的降低了开发效率和提高了心智负担。如果所有业务都是 CRUD ,prisma 的设计似乎也完全不考虑要实际开发的便利性。最简单的就是 update,delete 没有的数据会直接 Error ,这就引出了多一层 db 和 prisma 的心智负担。这种负担或者说设计让业务侧失去了便利性; model 的 relations 在实际开发中,尤其是 query 场景就几乎不可能把关系定义的完,也不可能依赖这种形式去定义。 |
37 justdoit123 146 天前 @zieglar 那是不是 prisma query 出来的数据,再装载到自己实现的实体 class 上? |
![]() | 38 BeautifulSoap 146 天前 @rocmax 你的这个写法,当用 mysql 的时候将会见到这样一副情景♂ ![]() 实际上真正 mysql 下能正常过类型检查并且正确执行的代码差不多这样的,堪称和类型检查还有工具斗智斗勇 ![]() 至于动态的 count ,我说的不是这种简单情景,比如我想 select 出一个表所有字段,然后再添加一个 count 或者其他动态字段,我必须在 select 中再手动写一遍所有字段(下图 q )。啥,照着官方文档 ...User 这样写?照着官文档写连类型检查都过不去(下图 q2) ![]() 说真的,用了这么多 typescript 的包,头一次遇到 drizzle 这种无时无刻不在花时间跟类型检查斗智斗勇的包♂ |
![]() | 39 raphaelsoul 146 天前 不是很喜欢他又自己引入一套 schema 语言 所以尝试了一次就丢弃了。 |
40 rocmax 146 天前 via Android @BeautifulSoap 这是两个事情,上面那个 sql<T>的类型标注是给 ts 侧看的不负责处理数据,你要根据实际返回的数据格式来标注给 ts ,数据本身是不用处理的。 下面那个用了 cast 所以没办法推断类型,应该在后面加一个 map With 做处理。 playground 没有 MySQL ,我有空搭个环境试试。 |
41 rocmax 146 天前 via Android @BeautifulSoap ...User 不行,需要...getTableColumns(User) |
42 qingjin 146 天前 还好吧,目前没遇到坑,用的挺香 |
![]() | 43 BeautifulSoap 146 天前 @rocmax 主要是 `...User` 这个用法是官方文档就这么写的♂ https://orm.drizzle.team/docs/select#count cast 是我复制错代码了,复制成了上面 Aggregations 部分的内容了。不过问题不大,我想吐槽的点不在 cast 上,还是出在...User 报错上。 |
![]() | 44 zieglar 145 天前 @justdoit123 #36 可以用自己的实体 class 直接承接 |
45 FlashEcho 145 天前 prisma 需要一个二进制文件,感觉特别不好,我试用了一下就转 drizzle 了 |
46 FlashEcho 145 天前 @BeautifulSoap #13 虽然我主力用 drizzle ,但是 drizzle 的文档确实很垃圾,而且感觉现在的 LLM 对于 drizzle 的理解不是很好 |