W
Wasp•3mo ago
CamBlackwood

Safest way to add a new required property to a schema model in a production project?

I have an existing project that has a number of existing users. On the User schema, I want to add a new property (a list of ints). This will be mandatory (although initiated as an empty list). What is the best way of dealing with this safely to ensure my prod database is not at risk?
5 Replies
kapa.ai
kapa.ai•3mo ago
Hi @CamBlackwood. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To safely add a new required property to a schema model in a production Wasp project, you should follow a forward-only migration approach. This method ensures that your production database remains stable and allows for a smooth transition. Here's the recommended process: 1. First, add the new field to your User entity in the main.wasp file, but make it optional:
entity User {=psl
id Int @id @default(autoincrement())
newProperty Int[] // Add this line
psl=}
entity User {=psl
id Int @id @default(autoincrement())
newProperty Int[] // Add this line
psl=}
2. Run wasp db migrate-dev to create a migration for this change. 3. Deploy this change to production. At this point, existing users will have a null value for the new property. 4. Update your application code to handle cases where the new property might be null, and set a default empty list where necessary. 5. Once you've confirmed that everything is working correctly with the optional field, you can create another migration to make the field required:
entity User {=psl
id Int @id @default(autoincrement())
newProperty Int[] @default([]) // Make it required with a default empty list
psl=}
entity User {=psl
id Int @id @default(autoincrement())
newProperty Int[] @default([]) // Make it required with a default empty list
psl=}
6. Run wasp db migrate-dev again to create a new migration for this change. 7. Deploy this second change to production. This approach allows you to maintain database compatibility between releases and minimizes the risk to your production environment. It's based on the principle of forward-only migrations, which is considered a best practice for safe database schema evolution. As mentioned in a GitHub issue discussion Wasp Issue #215 (https://github.com/wasp-lang/wasp/issues/215): "By doing this, you can migrate before deployment, and you don't worry about the application going down. Once you deploy, your two apps can exist simultaneously without any problems." Remember to always backup your production database before applying any migrations, just as an extra precaution. It's worth noting that Wasp doesn't currently have built-in features to enforce this kind of migration strategy, but following these steps manually will help ensure a safe transition for your production database. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @CamBlackwood, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
martinsos
martinsos•3mo ago
Yeah this is a good one, and I also wanted to suggest the principle of "forward-only" migrations. So as it said, first you add it as an optional field, but with default value of [], and you don't have to use it in your code yet anywhere, you just add it and apply that to production. Great, now you have that optioanl field in database that is empty for all users and will be [] for all new users, and does nothing, nobody uses it nor cares. Now you can fill it in for old users with some kind of one-off script, seed script or something. Great, now you have all users where you want them. Finally, your next change will be making that field required + adding the code that uses it.
CamBlackwood
CamBlackwoodOP•3mo ago
@martinsos makes sense - if I create it as madatory, would it populate all users with an empty list?
martinsos
martinsos•3mo ago
That's a good question, if that was so that would be perfect, but I doubt it, it sounds pretty invasive, that prisma does such a change. Although, I just asked chatGPT and it claims that Prisma would do it! Hm interesting. I would try it out locally, to confirm if this behaves so or not -> if it does, great, you can go with that!
miho
miho•3mo ago
You either have an optional (nullable) field which by default is null or you have a required (non nullable) field for which you specify a @default value. Have a non nullable field without a default is not possible, the migration script will fail 🙂 So ... if you have a sensible default - do it like that 🙂

Did you find this page helpful?