Налаштування PostgreSQL і MongoDB у Payload CMS
Payload 2.x підтримує два адаптери БД: PostgreSQL через Drizzle ORM і MongoDB через Mongoose. Вибір впливає на схему зберігання даних, можливості запитів та продуктивність.
PostgreSQL через Drizzle ORM
npm install @payloadcms/db-postgres
// payload.config.ts
import { postgresAdapter } from '@payloadcms/db-postgres'
export default buildConfig({
db: postgresAdapter({
pool: {
connectionString: process.env.DATABASE_URL,
// Або явні параметри:
host: 'localhost',
port: 5432,
database: 'payload_db',
user: 'payload',
password: process.env.DB_PASSWORD,
max: 20, // максимум з'єднань у пулі
idleTimeoutMillis: 30000,
},
push: false, // не пушити схему в production (використовувати міграції)
migrationDir: './migrations',
}),
})
Міграції Drizzle:
# Генерувати міграцію після змін колекцій
npx payload migrate:create
# Застосувати міграції
npx payload migrate
# Откат
npx payload migrate:down
# Статус
npx payload migrate:status
Міграції зберігаються у ./migrations/*.ts — можна редагувати вручну для складних змін схеми.
Схема зберігання в PostgreSQL:
-- Для колекції posts Payload створює таблиці:
SELECT table_name FROM information_schema.tables
WHERE table_name LIKE 'posts%';
-- posts — основні дані
-- posts_rels — зв'язки (relationship fields)
-- posts_locales — локалізовані поля (якщо ввімкнено)
-- _posts_v — версії (якщо ввімкнено версіонування)
-- _posts_v_locales — версії локалізованих полів
Прямі запити через Drizzle:
import { getPayload } from 'payload'
import config from '@payload-config'
const payload = await getPayload({ config })
const drizzle = payload.db.drizzle // прямий доступ до Drizzle екземпляра
// Raw SQL запит
const result = await drizzle.execute(
sql`SELECT p.*, COUNT(c.id) as comment_count
FROM posts p
LEFT JOIN comments c ON c.post_id = p.id
WHERE p.status = 'published'
GROUP BY p.id
ORDER BY comment_count DESC
LIMIT 10`
)
MongoDB через Mongoose
npm install @payloadcms/db-mongodb
import { mongooseAdapter } from '@payloadcms/db-mongodb'
export default buildConfig({
db: mongooseAdapter({
url: process.env.MONGODB_URI!,
// Параметри з'єднання
connectOptions: {
maxPoolSize: 10,
serverSelectionTimeoutMS: 5000,
},
}),
})
Прямий доступ до Mongoose:
const payload = await getPayload({ config })
const mongoose = payload.db.mongoose // mongoose екземпляр
// Нативний запит MongoDB
const result = await mongoose.connection.db
.collection('posts')
.aggregate([
{ $match: { status: 'published' } },
{ $group: { _id: '$category', count: { $sum: 1 } } },
{ $sort: { count: -1 } },
])
.toArray()
Порівняння адаптерів
| Критерій | PostgreSQL | MongoDB |
|---|---|---|
| Складні зв'язки | Краще (JOIN) | Через $lookup |
| Схема | Строга, міграції | Гнучка |
| Версіонування | Окремі таблиці _v |
Окремі колекції |
| Локалізація | Таблиці _locales |
Вкладений об'єкт |
| Хостинг | Supabase, Neon, Railway | MongoDB Atlas |
| Рекомендація для production | Так, для структурованих даних | Так, для гнучких схем |
Перемикання адаптерів
Перемкнути адаптер після запуску в production без міграції даних неможливо напряму — потрібен експорт/імпорт через Payload API. Вибір робиться на початку проекту.
Налаштування для production
// PostgreSQL в production — через SSL та connection pooling
db: postgresAdapter({
pool: {
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: true },
max: 10,
},
push: false, // ПОВИНЕН бути false в production
})
// Або через PgBouncer/Supabase Pooler
// connectionString: 'postgresql://user:[email protected]:6543/postgres?pgbouncer=true'
Терміни
Початкове налаштування адаптера БД з міграціями займає 0,5 дня. Оптимізація запитів та індексування для production займає 1 день.







