Persistent带有两个批量替换记录的操作:replace
和repsert
.使用时repsert
,如果要替换的记录最初不存在,则会将新记录插入到数据库中.使用replace
,如果要替换的记录不存在,则行为未定义.
这两个选项都不足以满足我的用例:如果(并且仅当)该键的记录已存在,我想替换记录.我可以检查记录是否存在,并且只有在返回记录时才尝试插入,但这似乎有可能存在竞争条件(尽管在这种情况下这种竞争条件不太可能产生有害影响).
是否有任何功能试图进行替换并根据成功或失败返回有用的结果?
我想使用这个简化的模式使用Persistent的现有数据库:
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Entity sql=entities
deriving Show
EntityLink sql=entity_links
sourceId EntityId
targetId EntityId
deriving Show
|]
Run Code Online (Sandbox Code Playgroud)
该entities
表有一id
列,很好.但是,该entity_links
表没有一个,我不想添加一个.相反,它有主键(source_id, target_id)
.每当我想插入一个EntityLink
,我得到这个运行时错误:
SqlError {sqlState = "42703", sqlExecStatus = FatalError, sqlErrorMsg = "column \"id\" does not exist", sqlErrorDetail = "", sqlErrorHint = ""}
Run Code Online (Sandbox Code Playgroud)
以下是我插入EntityLink
的代码,给出有效的sourceId
和targetId
:
insert $ EntityLink { entityLinkSourceId = sourceId
, entityLinkTargetId = targetId
}
Run Code Online (Sandbox Code Playgroud)
如何id
在Persistent中禁用该类型的列EntityLink
?
我正在用 Yesod 和 Persistent 编写一个 webapp。我有一个包含多个表的 SQL 数据库,其中包含我的“项目”的特征。我有一个主表和带有多个值的 Option 与 id 链接的额外表。
用户应该能够选择他想要过滤的那些特征并指定过滤器值。如果用户筛选操作系统,则 SQL 查询的许可证和编码将如下所示:
runquery :: (YesodPersist site, YesodPersistBackend site ~ SqlBackend) =>
String -> String -> String
-> HandlerT site IO [Entity Project]
runquery os license coding = runDB
$ select $ distinct
$ from $ \(p `InnerJoin` pl `InnerJoin` l `InnerJoin` pc
`InnerJoin` c `InnerJoin` o `InnerJoin` po) -> do
on $ p ^. ProjectId ==. pl ^. ProjectLicenseFkProjectId
on $ p ^. ProjectId ==. pc ^. …
Run Code Online (Sandbox Code Playgroud) 我遇到了以下编译错误:
• Couldn't match type ‘BaseBackend backend0’ with ‘SqlBackend’
arising from a use of ‘runSqlite’
The type variable ‘backend0’ is ambiguous
• In the expression: runSqlite ":memory:"
In the expression:
runSqlite ":memory:"
$ do { records <- selectList [UserUsername ==. "abc"] [LimitTo 10];
liftIO $ print (records :: [Entity User]) }
In an equation for ‘selectAll’:
selectAll
= runSqlite ":memory:"
$ do { records <- selectList [UserUsername ==. "abc"] [LimitTo 10];
liftIO $ print (records :: [Entity User]) }
Run Code Online (Sandbox Code Playgroud)
代码: …
我正在为Yesod中的资源编写REST API.我有一个POST方法应该尝试创建给定的资源,如果成功返回201和新创建的资源的ID.例如,
postResourceR :: Handler String
postResourceR = do
id <- runDB $ insert Resource
sendResponseStatus status201 id -- DOES NOT COMPILE
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误,这很简单:
No instance for (ToTypedContent (Key Resource))
arising from use of 'sendResponseStatus'
Run Code Online (Sandbox Code Playgroud)
我知道我想要的东西ToTypedContent
,但我找不到任何方法从Key
Database.Persist.Class中获取它.任何帮助将不胜感激.
编辑:
这是实际资源的定义:
Notification
title Text
content Text
icon Text Maybe
action Text Maybe
created UTCTime
updated UTCTime
deriving Show
Run Code Online (Sandbox Code Playgroud)