在Haskell Persistent库中手动创建外键插入实体的问题
解答
直接创建UserEntityId的解决方案
Persistent生成的UserEntityId类型,构造逻辑取决于实体定义方式:
- 若用模板Haskell自动生成实体代码,
UserEntityId是包裹Text的新类型,构造函数就是UserEntityId,接受Text参数。你当前写的UserEntityId (UUID.toText uid)逻辑正确,但需注意两点:- 确保传入的
uid对应的UserEntity存在于数据库中——数据库外键约束会校验这一点,不存在则插入失败。 - 确认
UserEntityId的构造函数名称和参数类型正确。可在GHCi中执行:t UserEntityId查看类型签名,验证是否接受Text作为参数。
- 确保传入的
无需查询UserEntity直接创建外键的做法是允许的,只要能保证用户ID的有效性。若代码编译报错,大概率是构造函数名称错误,或UUID转Text的格式与数据库中存储的用户ID格式不匹配。
使用cid替代key的修改方案
insertKey函数的返回值cid就是你传入的key本身,因此可以直接用cid替换key进行后续处理:
修改后的storeClap函数:
storeClap :: ConnectionPool -> ClapCreate -> IO ClapId storeClap pool clap = do let clapEntity = clapCreateToEntity clap key <- generateClapEntityKey cid <- runSql (insertKey key clapEntity) pool -- 直接使用cid代替原有的key case toUUID (unClapEntityKey cid) of Left err -> error $ show err Right uuid -> return $ ClapId uuid
更简洁的写法可省略key变量:
storeClap :: ConnectionPool -> ClapCreate -> IO ClapId storeClap pool clap = do let clapEntity = clapCreateToEntity clap cid <- runSql (insertKey =<< generateClapEntityKey <*> pure clapEntity) pool case toUUID (unClapEntityKey cid) of Left err -> error $ show err Right uuid -> return $ ClapId uuid
内容的提问来源于stack exchange,提问作者igr
相关产品推荐
相关产品推荐

