Yesod / Persistent中的外键约束?

时间:2015-05-05 20:30:56

标签: sqlite haskell yesod persistent

我正在尝试使用Database.Persistant为Scotty应用程序创建数据库,我无法弄清楚在表之间添加外键约束的语法。例如,我有一个User表和一个Post表,我希望Post表具有引用authorId UserId的属性User 1}}。这可以在原始SQL中很容易地完成,但我希望能够通过haskell访问数据而无需使用原始sql命令。此外,约束将是在数据库迁移时覆盖。这就是我目前定义数据库的方法:

share [mkPersist sqlSettings, mkMigrate "migrateAll"]
[persistLowerCase|
   User
     name String
     email String
     username String
     Primary username
     deriving Show
   Post
     title String
     content T.Text
     author String
     deriving Show
|]

这很好,但没有关键限制,这可能是一件非常糟糕的事情。 如果我尝试添加像the wiki on github这样的外键约束,通过将行Foreign User authorfk author添加到Post块,它编译得很好,但没有任何反应;不会发生迁移,也不会引入外键约束。

我做错了什么?任何帮助或建议将不胜感激。

要清楚,我想要的是Post中的author属性来引用User中的现有用户名。

1 个答案:

答案 0 :(得分:8)

Persistent使用Haskell类型系统生成外键。这就是没有特定字段类型来指示字段引用另一个表中的记录的原因。

您应该使用Persistent自动创建的密钥类型来指示密钥。

说我有UserArticle个表格。 Persistent会为您生成UserIdArticleId。然后,您将使用它们来表示此示例中的引用:

User
    username    Text
    password    Text
    email       Text
    description Text Maybe
    active      Bool

    UniqueUser  username
    UniqueEmail email

    deriving    Typeable

Article
    artname     Text
    title       Text
    keywords    Text Maybe
    description Text Maybe
    body        Markdown
    parent      ArticleId Maybe   -- optional Foreign Key
    user        UserId            -- required Foreign Key
    lastUpdate  UTCTime
    weight      Int
    public      Bool

    UniqueArt   artname

    deriving    Typeable

这个模型说:

  • Article可以使用Article类型的parent字段保存对其他ArticleId Maybe的引用。
  • Article必须包含对User字段user UserId字段的引用。

此示例将在PostgreSQL中生成以下article表:

                Table "public.article"
   Column    |           Type           |    Modifiers
-------------+--------------------------+----------------
 id          | integer                  | not null (...)
 artname     | character varying        | not null
 title       | character varying        | not null
 body        | character varying        | not null
 parent      | bigint                   | 
 user        | bigint                   | not null
 last_update | timestamp with time zone | not null
 weight      | bigint                   | not null
 public      | boolean                  | not null
 keywords    | character varying        |
 description | character varying        |

Indexes:
    "article_pkey" PRIMARY KEY, btree (id)
    "unique_art" UNIQUE CONSTRAINT, btree (artname)
Foreign-key constraints:
    "article_parent_fkey" FOREIGN KEY (parent)
                          REFERENCES article(id)
    "article_user_fkey" FOREIGN KEY ("user")
                        REFERENCES "user"(id)
Referenced by:
    TABLE "article" CONSTRAINT "article_parent_fkey"
                    FOREIGN KEY (parent)
                    REFERENCES article(id)

注意:如果使用SQLite,则必须确保启用了外键支持。请参见→SQLite Foreign Key Support: Enabling Foreign Key Support