Recipes › Move from SQLite to Postgres
Introduction
Content
Using content
Plugins
Recipes
Move from SQLite to Postgres
What you'll build
The same site on Postgres instead of SQLite: before launch (easy), or with content you want to keep. Uses: databases, migrations, backups.
SQLite is a fine choice for one server with a disk. Move to Postgres when you deploy to serverless, run several servers, or your host offers managed Postgres with backups.
Before launch: switch and start fresh
If the content so far is test content, switch the adapter and recreate it:
npm install @easy-cms/db-postgres @electric-sql/pglitepnpm add @easy-cms/db-postgres @electric-sql/pgliteyarn add @easy-cms/db-postgres @electric-sql/pglitebun add @easy-cms/db-postgres @electric-sql/pgliteimport { postgres } from '@easy-cms/db-postgres'
db: process.env.DATABASE_URL
? postgres({ url: process.env.DATABASE_URL })
: postgres({ pglite: '.pglite' }), // local Postgres in a folder, no server neededMigrations are written in one database's SQL, so replace the SQLite ones:
rm -r easy-cms/migrations
npx easy-cms migrate:create initrm -r easy-cms/migrations
pnpm exec easy-cms migrate:create initrm -r easy-cms/migrations
yarn easy-cms migrate:create initrm -r easy-cms/migrations
bunx easy-cms migrate:create initCommit the new folder, run npx easy-cms migrate where you deploy, and create the first admin
again (npx easy-cms create-admin).
With content to keep
easy-cms copy moves everything: documents, versions, users (so logins keep working), globals,
scheduled jobs. Ids stay the same, so relationships still point to the right documents.
-
Back up first:
npx easy-cms backup backups/before-postgres.db. -
Keep a config for the old database. Create
easy-cms.old.config.tsnext to the main config; it reuses everything and changes onlydb:easy-cms.old.config.ts import { sqlite } from '@easy-cms/db-sqlite' import config from './easy-cms.config' export default { ...config, db: sqlite({ url: 'file:./cms.db' }) } -
Point the main config at Postgres, as in the section above, and create the Postgres migrations (
rm -r easy-cms/migrations && npx easy-cms migrate:create init). -
Prepare the new database. Locally (PGlite, or
DATABASE_URLset) the next step creates the tables itself. For a production database runNODE_ENV=production npx easy-cms migratewith itsDATABASE_URLfirst. -
Copy, while nobody is editing:
npx easy-cms copy --from easy-cms.old.config.ts
# Copying from sqlite (easy-cms.old.config.ts) to postgres…
# ecms_users: 3
# ecms_posts: 42
# …
# Copied 318 row(s) from 17 table(s).pnpm exec easy-cms copy --from easy-cms.old.config.ts
# Copying from sqlite (easy-cms.old.config.ts) to postgres…
# ecms_users: 3
# ecms_posts: 42
# …
# Copied 318 row(s) from 17 table(s).yarn easy-cms copy --from easy-cms.old.config.ts
# Copying from sqlite (easy-cms.old.config.ts) to postgres…
# ecms_users: 3
# ecms_posts: 42
# …
# Copied 318 row(s) from 17 table(s).bunx easy-cms copy --from easy-cms.old.config.ts
# Copying from sqlite (easy-cms.old.config.ts) to postgres…
# ecms_users: 3
# ecms_posts: 42
# …
# Copied 318 row(s) from 17 table(s).The target must be empty, so running it twice by accident changes nothing. 6. Check the site: open the admin, a few documents with relationships and images, the history of a post, and log in.
Uploads don't move: they stay in uploads/ or your bucket, and documents keep pointing to them.
When the site runs well on Postgres, delete easy-cms.old.config.ts (keep the backup a while).
The same command works the other way, from Postgres to SQLite.