使用Haskell将数据从一个sqlite数据库批量传输到另一个的有效方法

时间:2019-05-14 13:39:05

标签: haskell

我想使用haskell将数据从一个数据库a移到另一个数据库b。我想知道对于散装插入物,最有效的方法是什么?我有以下代码可以正常工作,但与我使用相同查询编写的python代码相比,运行速度却慢得多。以下是我当前正在使用的代码:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}

import           Control.Applicative
import qualified Data.Text as T
import           Database.SQLite.Simple
import           Database.SQLite.Simple.FromRow
import qualified Data.Time.Clock as CLK
import           Control.Monad.IO.Class (liftIO)

type DatabaseName = String

data Pump = Pump 
  { rId :: Int
  , micropump_id :: Int
  , test_id :: Int 
  , signature :: T.Text
  , cycle :: Int
  , dispense :: T.Text
  , timestamp :: CLK.UTCTime
  } deriving (Eq, Show)

instance ToRow Pump where
  toRow (Pump a b c d e f g) = toRow (a,b,c,d,e,f,g) 

instance FromRow Pump where
  fromRow = Pump <$> field <*> field <*> field <*> field <*> field <*> field <*> field


extractPumpsFromDatabase :: DatabaseName -> Query -> IO [Pump]
extractPumpsFromDatabase n q = do
  conn <- open n
  r <- query_ conn (q) :: IO [Pump]
  close conn
  return r

addPumpsToDatabase :: (ToRow r) => DatabaseName -> Query -> [r] -> IO ()
addPumpsToDatabase n q r = do
  conn <- open n
  executeMany conn q r
  putStrLn ("Done: " ++ n) 

main :: IO ()
main = do
  conn <- open "databaseA.db"
  execute_ conn "CREATE TABLE IF NOT EXISTS micropumps (id INTEGER PRIMARY KEY, micropump_id INTEGER, test_id INTEGER, data TEXT, cycle INTEGER, dispense TEXT, timestamp TIMESTAMP)"
  close conn
  newPumps <- extractPumpsFromDatabase "databaseB"
  addPumpsToDatabase "databaseA" "INSERT INTO micropumps (id, micropump_id, test_id, data, cycle, dispense, timestamp) VALUES (?,?,?,?,?,?,?)" newPumps

花费很长时间来回泵类型吗?

1 个答案:

答案 0 :(得分:3)

一目了然:您没有使用交易。 python sqlite库确实(使我烦恼)执行自动事务管理,但是在您的情况下,这可能是造成速度差异的主要部分。尝试以下方法:

main :: IO ()
main = do
  conn <- open "databaseA.db"
  execute_ conn "CREATE TABLE IF NOT EXISTS micropumps (id INTEGER PRIMARY KEY, micropump_id INTEGER, test_id INTEGER, data TEXT, cycle INTEGER, dispense TEXT, timestamp TIMESTAMP)"
  close conn
  newPumps <- extractPumpsFromDatabase "databaseB"
  withTransaction conn $ 
    addPumpsToDatabase
      "databaseA"
      "INSERT INTO micropumps (id, micropump_id, test_id, data, cycle, dispense, timestamp) VALUES (?,?,?,?,?,?,?)"
      newPumps

编辑:请注意,在上述情况下,我使用的是已经关闭的conn。您真的不应该这样做,只需保持连接打开并将其作为参数传递给addPumpsToDatabase