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
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:
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:
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?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.@martinsos makes sense - if I create it as madatory, would it populate all users with an empty list?
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!
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 🙂