Aviary
Packages

@dudousxd/nestjs-media-database-drizzle

Drizzle media store (sqlite, and Postgres via /pg), migration-first.

A MediaStore backed by Drizzle ORM. The store is a POJO that receives your drizzle db handle.

import { DrizzleMediaStore, createMediaTable, mediaTable } from '@dudousxd/nestjs-media-database-drizzle';

createMediaTable(db);   // dev/test helper — see below
MediaModule.forRoot({ default: 's3', disks: { s3 }, store: new DrizzleMediaStore(db) });

Migration-first

Drizzle is migration-first by design — there's no runtime auto-schema. In production you manage the table with drizzle-kit using the exported mediaTable schema; createMediaTable(db) is a convenience for tests and quick dev setups that issues the CREATE TABLE IF NOT EXISTS.

Postgres (/pg)

Drizzle's schema is dialect-specific, so the package root ships the sqlite/libSQL schema and the Postgres flavour lives on its own subpath, @dudousxd/nestjs-media-database-drizzle/pg (built on drizzle-orm/pg-core). Its stores accept any drizzle Postgres database (PgDatabase — node-postgres, postgres-js, neon, pglite, …).

import { drizzle } from 'drizzle-orm/node-postgres';
import {
  DrizzlePgMediaStore,
  DrizzlePgUploadSessionStore,
  createMediaPgTables,
} from '@dudousxd/nestjs-media-database-drizzle/pg';

const db = drizzle(process.env.DATABASE_URL!);
await createMediaPgTables(db); // dev/test helper — use drizzle-kit migrations in production

MediaModule.forRoot({
  default: 's3',
  disks: { s3 },
  store: new DrizzlePgMediaStore(db),
  // resumable uploads: persist sessions + multipart ETags in Postgres
  uploadSessions: new DrizzlePgUploadSessionStore(db),
});
ExportWhat it is
mediaPgTablemedia table (jsonb properties/conversions, bigint size, timestamptz dates) — same logical shape as mediaTable
DrizzlePgMediaStoreMediaStore over mediaPgTable (count / aggregate / keyset-cursor list included)
mediaUploadSessionsPgTable, mediaUploadPartsPgTablemedia_upload_sessions + media_upload_parts (FK ON DELETE CASCADE, PK (session_id, part_number))
DrizzlePgUploadSessionStoreUploadSessionStore with every optional method: atomic addPart (INSERT … ON CONFLICT DO UPDATE), listParts, list({ disk, keyPrefix })
createMediaPgTables(db) / MEDIA_PG_DDLidempotent CREATE TABLE/INDEX IF NOT EXISTS for tests and dev
DrizzlePgDatabasethe accepted db type (PgDatabase<any, any, any>)

For drizzle-kit, re-export mediaPgTable, mediaUploadSessionsPgTable and mediaUploadPartsPgTable from your schema file and generate migrations as usual.

Attachment column

For the attachment column model — a single file as a JSON value object on your own table — use the attachment() custom column:

import { sqliteTable, text } from 'drizzle-orm/sqlite-core';
import { attachment } from '@dudousxd/nestjs-media-database-drizzle';

export const users = sqliteTable('users', {
  id: text('id').primaryKey(),
  avatar: attachment('avatar'), // Attachment | null, stored as JSON text
});

On write it JSON.stringifys the Attachment (or stores null); on read it rehydrates an Attachment. The column is sqlite/libSQL — for Postgres/MySQL define the equivalent JSON column in that dialect and (de)serialize with the value object's toJSON() / Attachment.fromJSON().

Peer dependencies

drizzle-orm (>=0.38 <1, tested on 0.45) and @dudousxd/nestjs-media-core, plus a driver (better-sqlite3, libsql, … — or pg / postgres for /pg). See Concepts → Persistence and Concepts → Attachments.

On this page