问题
I'm new to yesod and I'm trying to make the same blog project from this screencast: https://www.youtube.com/watch?v=SadfV-qbVg8 with the only difference being that I'm using MariaDB instead of PostgreSQL. Every time I add a new blog post and redirect to the page that shows it I see this error:
[Error#yesod-core] get BlogPostKey {unBlogPostKey = SqlBackendKey {unSqlBackendKey = 5}}: field article: Not a PersistText value @(yesod-core-1.4.12:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:577:5)
What exactly does that mean? If I look into the database, it has all the posts stored correctly. Why does it fail to load the posts from the database?
Here's the code
model
User
ident Text
password Text Maybe
UniqueUser ident
deriving Typeable
Email
email Text
user UserId Maybe
verkey Text Maybe
UniqueEmail email
BlogPost
title Text
article Markdown
PostDetails.hs (Gets the post from DB and shows it)
module Handler.PostDetails where
import Import
getPostDetailsR :: BlogPostId -> Handler Html
getPostDetailsR blogPostId = do
blogPost <- runDB $ get404 blogPostId
defaultLayout $ do
$(widgetFile "postDetails/post")
PostNew.hs (Creates a new post and stores it in the DB, after insertion, it redirects to PostDetails.hs with the new post)
module Handler.PostNew where
import Import
import Yesod.Form.Bootstrap3
import Yesod.Text.Markdown
blogPostForm :: AForm Handler BlogPost
blogPostForm = BlogPost
<$> areq textField (bfs ("Title" :: Text)) Nothing
<*> areq markdownField (bfs ("Article" :: Text)) Nothing
getPostNewR :: Handler Html
getPostNewR = do
(widget, enctype) <- generateFormPost $ renderBootstrap3 BootstrapBasicForm blogPostForm
defaultLayout $ do
$(widgetFile "posts/new")
postPostNewR :: Handler Html
postPostNewR = do
((res, widget), enctype) <- runFormPost $ renderBootstrap3 BootstrapBasicForm blogPostForm
case res of
FormSuccess blogPost -> do
blogPostId <- runDB $ insert blogPost
redirect $ PostDetailsR blogPostId
_ -> defaultLayout $(widgetFile "posts/new")
I don't understand why the compiler doesn't catch this error. When I create a post, instead of the title I se "Internal Server Error"
回答1:
This turned out to be caused by a bug in the persistent-mysql
package that's now fixed in persistent-mysql-2.3
.
Here's the root cause for those interested:
The MySQL C library (and by extension the Haskell mysql
package, which persistent-mysql
depends on) doesn't distinguish between binary and textual data at the type level. So if you saved a TEXT
value to the database, when it was looked it up by persistent it appeared to be binary data (a PersistByteString
).
This was fixed in #451 by checking the character set of the column, which the MySQL API docs recommend as the appropriate solution.
For more details, see that pull request or this issue.
Thanks for asking this question; I wouldn't have realized there was a bug otherwise.
来源:https://stackoverflow.com/questions/31902061/what-does-not-a-persisttext-value-mean