我正在尝试将markdown存储在一个具有MySQL后端的持久化模型的字段中。我将用例分解为:
型号:
TestModel
content MarkdownModel.hs:
import Text.Markdown (Markdown)
import Yesod.Text.Markdown ()
....这似乎创建了正确的迁移:
mysql> show columns in test_model;
+---------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| content | text | NO | | NULL | |
+---------+------------+------+-----+---------+----------------+但是,当我尝试从这个表中检索数据时,出现了一个异常。下面的示例来自cabal repl,但在应用程序运行时也会发生同样的情况:
repl> testid <- db $ insert $ TestModel $ Markdown "# Hello world"
[Debug#SQL] INSERT INTO `test_model`(`content`) VALUES(?); [PersistText "# Hello world"]
repl> testmodel <- db $ get testid
[Debug#SQL] SELECT `content` FROM `test_model` WHERE `id`=?; [PersistInt64 2]
*** Exception: runFakeHandler issue: InternalError "get TestModelKey {unTestModelKey = SqlBackendKey {unSqlBackendKey = 2}}: field content: Not a PersistText value"我的第一个猜测是TestModel构造函数的值是错误的,但即使在表单中使用markdownField创建对象时也会出现相同的错误:
testModelForm :: AForm Handler TestModel
testModelForm = TestModel
<$> areq markdownField "Content" Nothing
getTestModelR :: TestModelId -> Handler Html
getTestModelR testModelId = do
testmodel <- runDB $ get404 testModelId
....
08/Aug/2015:12:44:33 -0700 [Error#yesod-core] get TestModelKey {unTestModelKey = SqlBackendKey {unSqlBackendKey = 2}}: field content: Not a PersistText value @(yesod-core-1.4.12:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:577:5)有没有人以前见过这个异常并知道如何处理它?我能找到的关于这个错误的唯一文档是yesod-text-markdown的source code。
发布于 2015-09-02 11:42:44
事实证明,这是由现在persistent-mysql-2.3中修复的persistent-mysql包中的错误引起的。
这是那些感兴趣的人的根本原因:
Haskell C库(以及persistent-mysql所依赖的MySQL mysql包)在类型级别上不区分二进制和文本数据。因此,如果您将persistent值保存到数据库中,当通过TEXT查找它时,它看起来是二进制数据(一个PersistByteString)。
我在#451中通过检查列的字符集修复了这个问题,MySQL API文档推荐使用字符集作为适当的解决方案。
有关更多详细信息,请参阅拉取请求或this issue。
谢谢你问这个问题;否则我不会意识到有一个bug。
https://stackoverflow.com/questions/31898691
复制相似问题