UPDATE -找到错误的根本原因,但不知道如何解决
我刚刚发现,这种行为的根源不是使用sql=…,而是使用第一个表的主键作为外部和主键。
Post
topic String
deriving Show Eq
PostContent
Id PostId
content String
deriving Show Eq因此,问题仍然存在:
我可以用持久的方式表示主键是外键吗?-从的角度来看,这是有意义的(至少我认为是这样)?
原创
我正在做一个由simon HAXL pt1的乐趣给oracle/docker的haxl示例的端口--作为概念的证明。
我正在使用现有的sql脚本来生成db (在现实世界中,我的db表不在我手中)--我有以下的db布局
表后信息
| POSTID NUMBER | POSTDATE DATE | POSTTOPIC VARCHAR2(512 CHAR) |表后内容
| POSTID NUMBER | CONTENT CLOB |表后视图
| POSTID NUMBER | VIEWS INT |当然,我想表达的关系是,POSTID是postcontent中的一个外键&在相应的haskell持久QuasiQuoter中是postview中的唯一键。在是书之后,维基和测试用例从wiki链接起来。
我创建了以下模板haskell拼接:
share [ mkPersist sqlSettings {mpsGeneric = False} , mkMigrate "compositeMigrate" , mkDeleteCascade sqlSettings {mpsGeneric = False}] [persistUpperCase|
Post sql=POSTINFO
Id Int sql=POSTID
date UTCTime sql=POSTDATE
topic Text sql=POSTTOPIC
deriving Show Eq
PostContent sql=POSTCONTENT
Id PostId sql=POSTID
content Text sql=CONTENT
deriving Show Eq
PostViews sql=POSTVIEWS
Id PostId sql=POSTID
views Int sql=VIEWS
deriving Show Eq
|],它使用错误进行编译。
error:
• Not in scope: type constructor or class ‘PostId’
• In the quasi-quotation:
[persistUpperCase|
Post sql=POSTINFO
Id Int sql=POSTID
date UTCTime sql=POSTDATE
topic Text sql=POSTTOPIC
deriving Show Eq
PostContent
Id PostId sql=POSTID
content Text sql=CONTENT
deriving Show Eq
PostViews
Id PostId sql=POSTID
views Int sql=VIEWS
deriving Show Eq
|]有一点要注意的是,下面的测试用例是准商工作的,
Citizen
name String
age Int Maybe
deriving Eq Show
Address
address String
country String
deriving Eq Show
CitizenAddress
citizen CitizenId
address AddressId
Primary citizen address
deriving Eq Show下面是一个只运行错误和一些工作版本的最小示例(并相应地更改#define行)
> stack runhaskell --package persistent-template minimal.hsminimal.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE CPP #-}
module Minimal where
import Database.Persist.TH
#define FAILS
main :: IO ()
main = putStrLn "It works"
#ifdef WORKS
share [ mkPersist sqlSettings {mpsGeneric = False} , mkMigrate "compositeMigrate" , mkDeleteCascade sqlSettings {mpsGeneric = False}] [persistUpperCase|
Post sql=POSTINFO
Id Int sql=POSTID
topic String sql=POSTTOPIC
deriving Show Eq
|]
#endif
#ifdef ALSOWORKS
share [ mkPersist sqlSettings {mpsGeneric = False} , mkMigrate "compositeMigrate" , mkDeleteCascade sqlSettings {mpsGeneric = False}] [persistUpperCase|
Post sql=POSTINFO
Id Int sql=POSTID
topic String sql=POSTTOPIC
deriving Show Eq
PostContent sql=POSTCONTENT
post PostId sql=POSTID
content String sql=POSTCONTENT
deriving Show Eq
|]
#endif
#ifdef FAILS
share [ mkPersist sqlSettings {mpsGeneric = False} , mkMigrate "compositeMigrate" , mkDeleteCascade sqlSettings {mpsGeneric = False}] [persistUpperCase|
Post sql=POSTINFO
Id Int sql=POSTID
topic String sql=POSTTOPIC
deriving Show Eq
PostContent sql=POSTCONTENT
Id PostId sql=POSTID
content String sql=POSTCONTENT
deriving Show Eq
|]
#endif
-- UPDATE
#ifdef FAILSTOO
share [ mkPersist sqlSettings {mpsGeneric = False} , mkMigrate "compositeMigrate" , mkDeleteCascade sqlSettings {mpsGeneric = False}] [persistUpperCase|
Post
topic String
deriving Show Eq
PostContent
Id PostId
content String
deriving Show Eq
|]
#endif发布于 2016-12-23 14:52:06
我可以用持久的方式表示主键是外键吗?
是。假设Sqlite作为数据库的示例代码示例:
#!/usr/bin/env stack
{- stack
--resolver lts-7.14
--install-ghc
runghc
--package yesod
--package yesod-core
--package blaze-html
--package text
--package persistent
--package persistent-template
--package persistent-sqlite
--package shakespeare
--package aeson
-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Logger (runStderrLoggingT)
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
share
[mkPersist sqlSettings, mkMigrate "migrateAll"]
[persistLowerCase|
Post
topic String
deriving Show
PostContent
pid PostId
Primary pid
deriving Show
|]
main :: IO ()
main = mockMigration migrateAll在执行时,您可以得到以下内容:
CREATE TABLE "post"("id" INTEGER PRIMARY KEY,"topic" VARCHAR NOT NULL)
CREATE TABLE "post_content"("pid" INTEGER NOT NULL REFERENCES "post", PRIMARY KEY ("pid"))在上面的示例中可以看到,表post_content中的post_content列既是主键,也是外键。
https://stackoverflow.com/questions/41299818
复制相似问题