2013-10-05 101 views
16

我正在使用persistent來保存以下記錄(時間是UTCTime)。yesod persistent postgresql複合記錄

type Price = Int 
type Volume = Int 

share [mkPersist sqlSettings, mkMigrate "migrateBook"] 
    [persistLowerCase| 
    Level 
     limit  Price 
     volumes [Volume] 
     deriving Show Read Eq 

    Book 
     time  Time 
     asks  [Level] 
     bids  [Level] 
     deriving Show Read Eq 
    |] 

當我遷移的結構,我得到一個書籍表:

CREATE TABLE book 
(
id serial NOT NULL, 
"time" timestamp without time zone NOT NULL, 
asks character varying NOT NULL, 
bids character varying NOT NULL, 
CONSTRAINT book_pkey PRIMARY KEY (id) 
) 

和一張桌子等級:

CREATE TABLE level 
(
    id serial NOT NULL, 
    "limit" double precision NOT NULL, 
    volumes character varying NOT NULL, 
    CONSTRAINT level_pkey PRIMARY KEY (id) 
) 

當插入一本書,水平表保持空的,而書表包含一個包含預期記錄的JSON版本的條目。

問題:

我怎樣才能獲得持久的使用實際的簡單類型(例如int和時間)的列,而不是JSON的複雜類型?

是否持久知道如何存儲多對多的關係?

例如給出一個列表中的記錄A :: [B],我可以得到它創建第三個表

AId | B 
------- 
1 | b1 
1 | b2 etc 

我使用下列程序包:

persistent-postgresql-1.0.3 
yesod-persistent-1.1.0.1 
Postgres 9.1 
+1

持久性不會嘗試管理關係,因此您需要手動定義查找表。指定列表類型,如[Level],會導致整個列表被序列化爲單個字段,就像您觀察到的那樣。您可以使用「BookId」和「LevelId」等標識符來引用其他表的記錄。 –

回答

1

首先,對於[Level],存儲只需使用ID就可以將簡單類型存儲在json列表中。或者,如果需要跨關係進行查詢,則需要定義一個「through」或M2M表,就像在正常的關係數據庫設計中一樣。

type Price = Int 
type Volume = Int 

share [mkPersist sqlSettings, mkMigrate "migrateBook"] 
    [persistLowerCase| 
    Level 
     limit  Price 
     volumes [Volume] 
     deriving Show Read Eq 

    Book 
     time  Time 
     deriving Show Read Eq 

    BookAsk 
     book  BookId 
     level  LevelId 

    BookBid 
     book  BookId 
     level  LevelId 
    |] 

如對於該情況下,對於[Volume],問題是in persistent-postgresql。持久性被硬連線以將PersistList的值編碼爲JSON,而不是使用postgres對數組列類型的本機支持。如果你想解決這個問題,你需要提交問題或拉取請求。