Skip to content

Prisma migration adds updatedAt/createdAt as NOT NULL without defaults - breaks existing data #301

@borisno2

Description

@borisno2

Summary

When migrating from Keystone to OpenSaaS Stack, Prisma generates migrations that add updatedAt and make createdAt required without proper default value handling. This causes migration failures on databases with existing data.

Current Behavior

The generated migration adds updatedAt as NOT NULL without any default:

-- This fails on tables with existing data
ALTER TABLE "Account" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL;
ALTER TABLE "Bill" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL;
ALTER TABLE "BillItem" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL;
-- ... and 17 more tables

Similarly for making nullable createdAt required:

-- This fails if any rows have NULL createdAt
ALTER COLUMN "createdAt" SET NOT NULL;

PostgreSQL Error:

ERROR: column "updatedAt" of relation "Account" contains null values

Expected Behavior

When adding NOT NULL timestamp columns to existing tables, the migration should:

  1. Add the column with a default value for existing rows
  2. Then optionally remove the default if desired
-- Safe approach
ALTER TABLE "Account" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

Proposed Fixes

Option 1: Schema Generation (Recommended)

When OpenSaaS generates Prisma schemas, include @default(now()) for both fields:

createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt  // Add @default(now())

This ensures Prisma generates safer migrations with defaults.

Option 2: Migration Helper

Provide a pre-migration script that adds safe defaults before running the generated migration.

Option 3: Documentation

Document that users must manually edit generated migrations to add defaults when migrating existing data.

Affected Tables

From the emily-calder migration (20 tables total):

  • Account, Bill, BillItem, EmailSettings, Enrolment, ImportantDate
  • Instrument, Lesson, LessonAttendance, LessonCategory, LessonLength
  • LessonSchedule, LessonTerm, Message, Production, Student
  • Teacher, Term, User, XeroSettings

Workaround

Edit the generated migration file before running:

-- Change this:
ALTER TABLE "Account" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL;

-- To this:
ALTER TABLE "Account" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

Priority

High - This completely blocks migration on non-empty databases, requiring manual intervention for every migration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions