diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Changelog for persistent
 
+## 2.10.2
+
+* Added `runMigrationQuiet` and `runMigrationUnsafeQuiet` to `Database.Persist.Sql.Migration` as safer alternatives to `runMigrationSilent`. [#971](https://github.com/yesodweb/persistent/pull/971)
+  This functions as workaround/fix for: [#966](https://github.com/yesodweb/persistent/issues/966), [#948](https://github.com/yesodweb/persistent/issues/948), [#640](https://github.com/yesodweb/persistent/issues/640), and [#474](https://github.com/yesodweb/persistent/issues/474)
+* Added RawSql instances for 9, 10, 11 and 12-column results. [#961](https://github.com/yesodweb/persistent/pull/961)
+
 ## 2.10.1
 
 * Added `constraint=` attribute to allow users to specify foreign reference constraint names.
diff --git a/Database/Persist/Sql.hs b/Database/Persist/Sql.hs
--- a/Database/Persist/Sql.hs
+++ b/Database/Persist/Sql.hs
@@ -40,6 +40,8 @@
 import Database.Persist.Sql.Orphan.PersistUnique ()
 
 -- | Commit the current transaction and begin a new one.
+-- This is used when a transaction commit is required within the context of 'runSqlConn'
+-- (which brackets its provided action with a transaction begin/commit pair).
 --
 -- @since 1.2.0
 transactionSave :: MonadIO m => ReaderT SqlBackend m ()
@@ -58,6 +60,8 @@
     liftIO $ connCommit conn getter >> connBegin conn getter (Just isolation)
 
 -- | Roll back the current transaction and begin a new one.
+-- This rolls back to the state of the last call to 'transactionSave' or the enclosing
+-- 'runSqlConn' call.
 --
 -- @since 1.2.0
 transactionUndo :: MonadIO m => ReaderT SqlBackend m ()
diff --git a/Database/Persist/Sql/Class.hs b/Database/Persist/Sql/Class.hs
--- a/Database/Persist/Sql/Class.hs
+++ b/Database/Persist/Sql/Class.hs
@@ -197,6 +197,77 @@
 to8 :: ((a,b),(c,d),(e,f),(g,h)) -> (a,b,c,d,e,f,g,h)
 to8 ((a,b),(c,d),(e,f),(g,h)) = (a,b,c,d,e,f,g,h)
 
+-- | @since 2.10.2
+instance (RawSql a, RawSql b, RawSql c,
+          RawSql d, RawSql e, RawSql f,
+          RawSql g, RawSql h, RawSql i)
+       => RawSql (a, b, c, d, e, f, g, h, i) where
+    rawSqlCols e         = rawSqlCols e         . from9
+    rawSqlColCountReason = rawSqlColCountReason . from9
+    rawSqlProcessRow     = fmap to9 . rawSqlProcessRow
+
+-- | @since 2.10.2
+from9 :: (a,b,c,d,e,f,g,h,i) -> ((a,b),(c,d),(e,f),(g,h),i)
+from9 (a,b,c,d,e,f,g,h,i) = ((a,b),(c,d),(e,f),(g,h),i)
+
+-- | @since 2.10.2
+to9 :: ((a,b),(c,d),(e,f),(g,h),i) -> (a,b,c,d,e,f,g,h,i)
+to9 ((a,b),(c,d),(e,f),(g,h),i) = (a,b,c,d,e,f,g,h,i)
+
+-- | @since 2.10.2
+instance (RawSql a, RawSql b, RawSql c,
+          RawSql d, RawSql e, RawSql f,
+          RawSql g, RawSql h, RawSql i,
+          RawSql j)
+       => RawSql (a, b, c, d, e, f, g, h, i, j) where
+    rawSqlCols e         = rawSqlCols e         . from10
+    rawSqlColCountReason = rawSqlColCountReason . from10
+    rawSqlProcessRow     = fmap to10 . rawSqlProcessRow
+
+-- | @since 2.10.2
+from10 :: (a,b,c,d,e,f,g,h,i,j) -> ((a,b),(c,d),(e,f),(g,h),(i,j))
+from10 (a,b,c,d,e,f,g,h,i,j) = ((a,b),(c,d),(e,f),(g,h),(i,j))
+
+-- | @since 2.10.2
+to10 :: ((a,b),(c,d),(e,f),(g,h),(i,j)) -> (a,b,c,d,e,f,g,h,i,j)
+to10 ((a,b),(c,d),(e,f),(g,h),(i,j)) = (a,b,c,d,e,f,g,h,i,j)
+
+-- | @since 2.10.2
+instance (RawSql a, RawSql b, RawSql c,
+          RawSql d, RawSql e, RawSql f,
+          RawSql g, RawSql h, RawSql i,
+          RawSql j, RawSql k)
+       => RawSql (a, b, c, d, e, f, g, h, i, j, k) where
+    rawSqlCols e         = rawSqlCols e         . from11
+    rawSqlColCountReason = rawSqlColCountReason . from11
+    rawSqlProcessRow     = fmap to11 . rawSqlProcessRow
+
+-- | @since 2.10.2
+from11 :: (a,b,c,d,e,f,g,h,i,j,k) -> ((a,b),(c,d),(e,f),(g,h),(i,j),k)
+from11 (a,b,c,d,e,f,g,h,i,j,k) = ((a,b),(c,d),(e,f),(g,h),(i,j),k)
+
+-- | @since 2.10.2
+to11 :: ((a,b),(c,d),(e,f),(g,h),(i,j),k) -> (a,b,c,d,e,f,g,h,i,j,k)
+to11 ((a,b),(c,d),(e,f),(g,h),(i,j),k) = (a,b,c,d,e,f,g,h,i,j,k)
+
+-- | @since 2.10.2
+instance (RawSql a, RawSql b, RawSql c,
+          RawSql d, RawSql e, RawSql f,
+          RawSql g, RawSql h, RawSql i,
+          RawSql j, RawSql k, RawSql l)
+       => RawSql (a, b, c, d, e, f, g, h, i, j, k, l) where
+    rawSqlCols e         = rawSqlCols e         . from12
+    rawSqlColCountReason = rawSqlColCountReason . from12
+    rawSqlProcessRow     = fmap to12 . rawSqlProcessRow
+
+-- | @since 2.10.2
+from12 :: (a,b,c,d,e,f,g,h,i,j,k,l) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l))
+from12 (a,b,c,d,e,f,g,h,i,j,k,l) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l))
+
+-- | @since 2.10.2
+to12 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l)) -> (a,b,c,d,e,f,g,h,i,j,k,l)
+to12 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l)) = (a,b,c,d,e,f,g,h,i,j,k,l)
+
 extractMaybe :: Maybe a -> a
 extractMaybe = fromMaybe (error "Database.Persist.GenericSql.extractMaybe")
 
diff --git a/Database/Persist/Sql/Migration.hs b/Database/Persist/Sql/Migration.hs
--- a/Database/Persist/Sql/Migration.hs
+++ b/Database/Persist/Sql/Migration.hs
@@ -5,8 +5,10 @@
   , showMigration
   , getMigration
   , runMigration
+  , runMigrationQuiet
   , runMigrationSilent
   , runMigrationUnsafe
+  , runMigrationUnsafeQuiet
   , migrate
   -- * Utilities for constructing migrations
   , reportErrors
@@ -16,6 +18,7 @@
   ) where
 
 
+import Control.Exception (throwIO)
 import Control.Monad (liftM, unless)
 import Control.Monad.IO.Unlift
 import Control.Monad.Trans.Class (MonadTrans (..))
@@ -80,8 +83,26 @@
              -> ReaderT SqlBackend m ()
 runMigration m = runMigration' m False >> return ()
 
+-- | Same as 'runMigration', but does not report the individual migrations on
+-- stderr. Instead it returns a list of the executed SQL commands.
+--
+-- This is a safer/more robust alternative to 'runMigrationSilent', but may be
+-- less silent for some persistent implementations, most notably
+-- persistent-postgresql
+--
+-- @since 2.10.2
+runMigrationQuiet :: MonadIO m
+                  => Migration
+                  -> ReaderT SqlBackend m [Text]
+runMigrationQuiet m = runMigration' m True
+
 -- | Same as 'runMigration', but returns a list of the SQL commands executed
 -- instead of printing them to stderr.
+--
+-- This function silences the migration by remapping 'stderr'. As a result, it
+-- is not thread-safe and can clobber output from other parts of the program.
+-- This implementation method was chosen to also silence postgresql migration
+-- output on stderr, but is not recommended!
 runMigrationSilent :: MonadUnliftIO m
                    => Migration
                    -> ReaderT SqlBackend m [Text]
@@ -99,7 +120,7 @@
 runMigration' m silent = do
     mig <- parseMigration' m
     if any fst mig
-        then error $ concat
+        then liftIO . throwIO . PersistError . pack $ concat
                  [ "\n\nDatabase migration: manual intervention required.\n"
                  , "The unsafe actions are prefixed by '***' below:\n\n"
                  , unlines $ map displayMigration mig
@@ -115,9 +136,24 @@
 runMigrationUnsafe :: MonadIO m
                    => Migration
                    -> ReaderT SqlBackend m ()
-runMigrationUnsafe m = do
+runMigrationUnsafe m = runMigrationUnsafe' False m >> return ()
+
+-- | Same as 'runMigrationUnsafe', but returns a list of the SQL commands
+-- executed instead of printing them to stderr.
+--
+-- @since 2.10.2
+runMigrationUnsafeQuiet :: MonadIO m
+                        => Migration
+                        -> ReaderT SqlBackend m [Text]
+runMigrationUnsafeQuiet = runMigrationUnsafe' True
+
+runMigrationUnsafe' :: MonadIO m
+                    => Bool
+                    -> Migration
+                    -> ReaderT SqlBackend m [Text]
+runMigrationUnsafe' silent m = do
     mig <- parseMigration' m
-    mapM_ (executeMigrate False) $ sortMigrations $ allSql mig
+    mapM (executeMigrate silent) $ sortMigrations $ allSql mig
 
 executeMigrate :: MonadIO m => Bool -> Text -> ReaderT SqlBackend m Text
 executeMigrate silent s = do
diff --git a/persistent.cabal b/persistent.cabal
--- a/persistent.cabal
+++ b/persistent.cabal
@@ -1,5 +1,5 @@
 name:            persistent
-version:         2.10.1
+version:         2.10.2
 license:         MIT
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
