P
Prisma•2mo ago
ImEgg

Mongodb, Making Breaking changes to production database

Hi, I'm trying to understand what the suggested way or best practices for making breaking changes to a database in production are. for simplicity sake, let's say I have a schema for mongodb:
model User {
id String
tenant_id String
email String @unique
password String
line_one String
city String
state String
zip String
@@map("users")
}
model User {
id String
tenant_id String
email String @unique
password String
line_one String
city String
state String
zip String
@@map("users")
}
where there is already data present. let's say now I want to be able to have multiple addresses so I want the schema to be put like this:
model User {
id String
tenant_id String
email String @unique
password String
//assume type is of same fields
address Address[]
@@map("users")
}
model User {
id String
tenant_id String
email String @unique
password String
//assume type is of same fields
address Address[]
@@map("users")
}
To add the new address field is okay but the moving of existing data from the 4 separate fields to now the new address object is what I am having a hard time understanding how to do. I'd like to understand how people are doing these types of database changes for mongodb with prisma or just in general I suppose. thanks!
3 Replies
RaphaelEtim
RaphaelEtim•2mo ago
Hi @ImEgg 👋 One way to approach this would be to add the new address field to your schema:
model User {
id String
tenant_id String
email String @unique
password String
line_one String
city String
state String
zip String
address Address[]
@@map("users")
}

model Address {
street String
city String
state String
zip String
user User @relation(fields: [userId], references: [id])
userId String
}
model User {
id String
tenant_id String
email String @unique
password String
line_one String
city String
state String
zip String
address Address[]
@@map("users")
}

model Address {
street String
city String
state String
zip String
user User @relation(fields: [userId], references: [id])
userId String
}
Then, update your application to start writing to both the new address field and the old fields when creating or updating users. You can create a migration script to move the existing address data into the new address array for all users. This script would: 1. Query all users 2. For each user, create a new Address object with the data from the existing fields 3. Add this new Address object to the user's address array 4. Save the updated user After running the migration script and ensuring all data has been moved, you can update your application to exclusively use the new address field. Finally, you can create another migration to remove the old address fields from your schema.
RaphaelEtim
RaphaelEtim•2mo ago
ImEgg
ImEggOP•2mo ago
I see. According to documentation, the strategy I am referring to would be "all-at-once" updates. From what it sounds like, the best way to go about this is to have the script run in your CI/CD pipeline. if it fails, the push fails and that for every breaking change, there should be 2 separate migrations. the first one adds and moves data to new field. once we do checks and balances and are okay with results we make the second migration to remove old field / data if need be. Please correct me if I'm wrong here. 2nd question. For Prisma with SQL, there is a migration folder and migrations tracker table in the db itself. Is the recommended idea to try and mimic this solution for mongodb if the idea is to do "all-at-once" updates similar to it. Thank you for your help. I appreciate it!
Want results from more Discord servers?
Add your server