
A change is in the client's database. Tonight, three proofs, in a repository and a database you or the client can open. Name the migration the deploy applied: the name on the history, and the schema the database is actually on. Show a migration file that is in the repository and not applied, or write that you cannot see the history table. Then show a different database, the one you meant to leave alone, still on the version you named for it. If any of the three requires the person who pressed deploy and then left, you have not named the migration. You have a folder and a hope.
This is the schema version one database has applied. It is not the digest of the process that is running. Name the commit the client is running is that digest, and whether it is the commit you believe you shipped. A running image can be new while the schema is old, and a schema can be new while the image is old. It is not the version a lockfile resolved. Name the package the lockfile pinned is one dependency, the range, and the exact version. A pin is not a table. It is not the action a workflow fetched. Name the action the workflow runs is the uses ref. A third-party action can apply a migration and still not be the migration. It is not the check the merge required. Name the check the merge required is a status on a pull request. A green check can pass on a branch whose migration has not been applied anywhere. It is not the license a dependency added. Name the license the build added is the grant. A grant does not say which tables exist.
None of what follows is a count of this client's deploys, and none of it is legal advice. The study below counted schema changes in ten open-source PHP applications, through early 2012, in Subversion. The vendor page below describes one migration tool's history. A wiki's revision from 2011 is not this database. A tool's warning text is not a finding that the tool is the one this repository uses. They do tell you the shape of a proof an agency can perform before it tells the client the deploy landed.
Dong Qiu, Bixin Li, and Zhendong Su, at ESEC/FSE 2013, studied the co-evolution of schema and code in ten database applications. The abstract's corpus is over 160K revisions. That figure is the applications' revision histories, not the revisions that touched a schema. Table 3, which is the schema cut, prints 2,744 database revisions, 1,464 of them valid, 53.4%, and 6,417 atomic schema changes, 4.4 per valid revision. 2,744 is not over 160K. 1,464 is not 2,744. 6,417 is not 1,464. 4.4 is not 53.4. The ten rows add to those totals. Open-source Subversion through the windows in their Table 1 is not this client's private repository (Qiu, Li, and Su, An Empirical Analysis of the Co-evolution of Schema and Code).
Valid is a filter, not a compliment. A database revision is a commit that touches a schema file. A valid one is a database revision that is not only a syntax tweak, a comment, a reformat, a data change, a DBMS-version tweak, a system marker, or a rollback. They filtered both sides of a rollback. Joomla is the cell that explains the prose. 532 database revisions, 133 valid, 25.0%, because data statements and schema statements share a file. The prose says the valid share falls mostly in the 50 to 90 percent range. 25.0 is not in that range, and the paper says so by explaining Joomla. PrestaShop is 221 and 203, 91.9%. 91.9 is not "mostly" 50 to 90 either. Mediawiki is 377 and 221, 58.6%, 892 atomic changes, 4.0 per valid revision. Tikiwiki is the large cell: 941 database revisions, 493 valid, 2,208 atomic changes. 2,208 is not 6,417. Roundcube is the small one: 56 and 45, 101 atomic changes. 101 is not 2,208. The per-valid column falls mostly in a 2 to 7 range. 4.4, the overall average, sits in that range. It is not every row. webERP prints 7.0. Coppermine prints 1.7. 7.0 is not 1.7.
How often, in their words, is a different table from how many. For each release they saw around 5 to 25 valid database revisions and 15 to 180 atomic changes. For each year, around 10 to 65 valid revisions and 15 to 300 atomic changes. The result line is then an average: 65 atomic changes per release and 90 per year, across the ten projects. 65 is not the 15 to 180 range, and 90 is not 65. 5 is not 25. Seven projects reached 60% of their maximum schema size in about 20% of the selected lifecycle. 60 is not 20. 7 is not 10. Growth and change are different columns. Mediawiki's table growth prints 1600% and its table change prints 2300%. The column pair prints 1181% and 1611%. 1600 is not 2300. 1181 is not 1600. e107's table growth prints -9%, and its table change prints 70%. A negative growth is not a quiet schema. Do not average -9 with 1600 and call it the study.
What kind of change, and what it did to code, are two more cuts. Six high-level categories, and 24 atomic types under them. Transformations, structure refactoring, and data-quality refactoring cover more than 80% of schema changes across all ten projects and over 95% across seven. 80 is not 95. Architectural refactoring occurred in 8 projects. Referential-integrity refactoring occurred in only three. Method refactoring, the stored-procedure pair, did not occur in any of the ten. 0 projects is not 3, and 3 is not 8. Addition was the most frequent operation in 9 of the 10, about 40% of operations across all ten and over 50% in five. Addition and change together were around 80%. 40 is not 50 is not 80. 9 is not 10. PrestaShop revision 476 changed a column from INTEGER to INT(10) and accounted for 26.2% of that project's schema changes. 26.2 is not a share of 6,417. Around 60% to 90% of schema changes happened in 20% of the tables, and most tables, around 40%, rarely changed. The abstract's sentence is 80% of changes in 20 to 30 percent of the tables, and nearly 40% of tables did not change. 20 to 30 is not 20. Nearly 40% did not change is not the body's around 40% rarely changed. Do not pick the rounder one and drop the other.
Co-change is an estimate of impact, and their own manual study limits it. For each atomic change, around 10 to 100 lines of code changed on average. For each valid database revision, which they say typically contains 2 to 5 atomic changes, around 100 to 1,000 lines. 2 to 5 is not the 2 to 7 range on the earlier column, and 4.4 is not 2. 10 lines is not 1,000. About 27% of valid database revisions did not provide useful co-change information, precision 0% for the two situations where the code change was not actually the schema's. 27 is not 0, and 0% precision is not "no code changed." Of the revisions that did land in the other two situations, over 80% had precision over 60%, over 70% had precision over 80%, and about 56% had 100% precision. 56 is not 80. 100 is not 60. A separate 10% is the random sample they inspected by hand to check the diff tool. That 10% is not the 27%. They also write that referential integrity constraints and stored procedures are rarely used in the studied subjects. Rarely, in that sentence, is the same finding as method refactoring occurring in none of the ten and referential integrity in only three. It is not a new denominator.
A migration tool's history is a different object from that corpus, and it is the object you can open tonight if this repository uses it. Prisma's migration history is two stores. A prisma/migrations folder, one subfolder and a migration.sql for each migration, is the source of truth for the data model. A _prisma_migrations table in the database is how the tool checks three things: whether a migration ran against the database, whether an applied migration was deleted, and whether an applied migration was changed. The folder is not the table. A file that exists only on a laptop has not been applied. A row that exists only in production is not in the folder you are reading. The page says you must commit the entire folder, including migration_lock.toml, which detects an attempted provider change. Committing schema.prisma is not enough. prisma migrate deploy, the command for production and test, runs migration files. It does not look at the schema to decide the models. A schema file that matches your intention, and a history the deploy will not run, is a picture of the database. It is not the database (Prisma, Migration histories).
Editing a migration that already applied is the failure the page walks through, and the numbers in the walkthrough are an example, not a census. They change VARCHAR(550) to VARCHAR(560) inside a migration that development has already applied. 550 is not 560. prisma migrate dev then errors because a migration changed, and a reset replays every migration, including the edited one. After the replay, the tool compares the history's end state to the schema, which still says 550, and generates a new migration back to 550. From then on, migrate deploy warns that histories do not match, even though the schema end states match. The warning in the example reads 6 migrations found, and names 20210310143435_change_type as modified since it was applied. 6 is the example's count of files. It is not a limit, and it is not 1,464. The timestamp in that warning is not a production clock. A change that looks harmless after a reset can hide a production bug you cannot reproduce in development, or the reverse. The page's advice is to restore the file or revert the edit, not to reset your way out of the warning. A reset that makes the laptop match the edited file has not shown production.
Do the three proofs on one real deploy, in the history the database actually has. First, the name. Copy the migration name the history table records as applied, and copy the folder name in the repository. If they differ, write both. If the table is missing, write that, and do not infer the schema from schema.prisma. Second, the gap. Show one file that is in the folder and not applied, or show that every file has a row and the tool is not warning that an applied file was edited. A warning you dismissed is part of the proof. It is not a green deploy. Third, the other database. The environment you did not mean to migrate is still on the version you named for it. If production and development now share a history you edited on one side only, you have the page's bug, not a finished deploy. If you cannot open the table because a vendor holds it, write that, and do not tell the client the migration landed.
Three moves feel like the proof and are a second problem. Running the SQL by hand in a console, because the history table is annoying, and then describing the tables as migrated. The tables may match. The next deploy does not know. Editing an old migration so the folder matches production, which is the VARCHAR example, and then resetting development until the warning goes quiet. Asking a model whether the migration ran. The model can read the file. It cannot see the table, unless you pasted the table, in which case you already had the proof and did not need the model. A commit you can name, while the schema is a different version, is name the commit the client is running. The digest does not apply the SQL. A check that passed, while the migration is unapplied, is name the check the merge required. A status is not a schema.
The shape of a system that can be wrong about its own data, without this page becoming a case study of that system, is a search index rather than a history table. Haystack is one search layer across documents, data lakes, and repositories, with indexing, document management for structured and unstructured data, and workflow automation. The shape that matters here is a platform whose data is not the schema file. That case is not a migration ledger. Nothing in the description is a headcount, a duration, or a result figure. If the only record of a schema change is a search document someone uploaded, you do not have this proof. You have a writeup.
There is a version of this deploy where hiring the path is the wrong purchase. The work is not sold, so there is no repository and no database. The client asked to meet the people who will build, and the document in front of you is a term sheet. The criteria for that choice sit on the page written for a top saas development company. That page is criteria. It does not rank anyone, including us. The room only has a slide, or the buyer only wants a template of a migrations folder. A template is not an applied row. Or the buyer wants a legal opinion about who owns the schema. Hire the lawyer.
When the deploy is real and the history is not on a screen you can open, the missing object is specific. The applied name, a file that was not applied or a warning that an applied file changed, and a second database still on its own version. A white label software development partner that expects this will put the history where the client can read it, before the first production deploy, because a folder on a laptop you do not hold is not a migration you can name. One that can only paste a screenshot of a terminal is telling you who holds the schema. Where the next slice is one capability and the acceptance sentence names the applied migration, an AI integration sprint is the shape that can require the three proofs as the definition of done. Where you are not sure which database the current engagement migrates, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a schema version, and they are not 65 changes per release.
A factor an account enrolled, and the tokens one model response billed, are different objects: show the factor they enrolled and name the tokens the response billed. Do not record either on this page. An authenticator is not a migration. A token count is not a table.
Before you tell the client the deploy landed, do the three proofs and write the name. Name the migration the database applied, or write that the history was not there. Show a file that was not applied, or show the warning that an applied file changed. Show the other database still on its version. Do not edit the old file to silence the warning, and do not ask a model what ran. A 2013 corpus can tell you that schemas and code drift apart. The history table is the page you can defend.
Find this useful? Tell Google to show you more of it.
