Skip to main content

How to Create a MySQL Account for Running Migrations

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

An app shouldn't be able to change tables, but migrations have to. So they get their own account. To find exactly which rights it needs, I applied a real set of EF Core migrations to an empty database, taking away one right each time.

What You Need​

MySQL 9.7, an administrator's session, and a strong password from How to Generate a Strong Random Password in the Terminal.

Step 1: Create the Account​

mysql>
CREATE USER 'inventory_migrator'@'%' IDENTIFIED BY 'a-password-of-your-own';
GRANT CREATE, ALTER, DROP, INDEX, REFERENCES, SELECT, INSERT, DELETE ON inventory.* TO 'inventory_migrator'@'%';
SHOW GRANTS FOR 'inventory_migrator'@'%';
Output
+-------------------------------------------------------------------------------------------------------------------+
| Grants for inventory_migrator@% |
+-------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `inventory_migrator`@`%` |
| GRANT SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER ON `inventory`.* TO `inventory_migrator`@`%` |
+-------------------------------------------------------------------------------------------------------------------+

SHOW GRANTS for inventory_migrator listing SELECT, INSERT, DELETE, CREATE, DROP, REFERENCES, INDEX and ALTER on the inventory database.

Why These Eight​

I started each run with an empty database, and an account with all nine candidate rights except one. These are real runs of EF Core 10 migrations, using Oracle's provider. They create six tables, with indexes and foreign keys:

WithoutApplyingTables leftFirst error
CREATEFails0CREATE command denied … for table '__EFMigrationsHistory'
ALTERFails4ALTER command denied … for table 'stock_movements'
INDEXFails3INDEX command denied … for table 'categories'
REFERENCESFails2REFERENCES command denied … for table 'rights_demo.categories'
SELECTFails1SELECT command denied … for table '__EFMigrationsHistory'
INSERTFails3INSERT command denied … for table '__EFMigrationsHistory'
DROPWorks6None
UPDATEWorks6None
DELETEWorks6None

So applying these migrations needs six rights. Then I tried rolling them all back, with dotnet ef database update 0:

WithoutRolling backFirst error
NothingWorksNone
DROPFailsDROP command denied … for table 'order_lines'
DELETEFailsDELETE command denied … for table '__EFMigrationsHistory'
UPDATEWorksNone

That makes eight. UPDATE isn't on the list because none of these migrations change any rows. If one of yours does, with migrationBuilder.Sql("UPDATE …"), add it. A future migration that removes a column may need DROP going forward too, so keep it.

A Failure Leaves Half the Work Behind​

Look at the "Tables left" column. MySQL can't roll back a CREATE TABLE, so a migration that fails partway leaves everything it had done so far. That's why it's worth finding the rights before a real run.

Step 2: Use It​

Give the app one connection string, and the migration step another. With EF Core, How to Run EF Core Migrations with a Different Database Account shows how. It worked on a real migration, adding a column:

Output (the end)
Applying migration '20261106062549_AddProductBarcode'.
Done.

Common Mistakes​

MistakeWhat happensDo this instead
Using the app's accountCREATE command deniedUse this one
Using rootWorks, with far more than it needsUse this one
Keeping this password with the app's settingsA stolen app gets these rights tooGive it only to the migration step
ON *.*It can change every databaseName the database

Troubleshooting​

SymptomLikely causeFix
UPDATE command denied in a migrationYour migration changes rowsAdd UPDATE
ROUTINE, TRIGGER or VIEW errorsYour migrations create thoseAdd CREATE ROUTINE, TRIGGER or CREATE VIEW
Tables left over after a failureMySQL can't roll back DDLFix the rights, then drop what it left, or finish by hand

Conclusion​

These migrations need CREATE, ALTER, DROP, INDEX, REFERENCES, SELECT, INSERT, DELETE. Give those to an account only the migration step uses, and find out what yours need before a real run.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.