I'm am developing an application using NestJS and TypeORM. Whenever I try to generate migrations from my entities (by running typeorm migration:generate
) I get the following message:
No changes in database schema were found - cannot generate a migration. To create a new empty migration use "typeorm migration:create" command
I even deleted all the existing migration files (from migrations folder) to exclude any possibility of conflict.
The problem begun after I changed my application's modules folders structure to:
src
|- config
| |- database
| |- mysql
| |- cli-configuration.ts
|- migrations
|- module1
|- controller
|- entity
|- service
As can be seen, the migrations
folder is right under src
and each module has an entity
folder, where the entities for that module are placed. All the ormconfig settings come from cli-configuration.ts
file.
In package.json
file I added the following to scripts
:
{
...
"scripts": {
...
"typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js --config src/config/database/mysql/cli-configuration.ts",
"typeorm:migrate": "npm run typeorm migration:generate -- -n",
"typeorm:run": "npm run typeorm migration:run"
}
}
The content of src/config/database/mysql/cli-configuration.ts
file is:
import * as path from 'path';
import * as dotenv from 'dotenv';
dotenv.config({
// Path relative to project root folder (because cli command is invoked from there)
path: path.resolve('environment', (process.env.NODE_ENV === "production") ? ".env.production" : ".env")
});
const config = {
type: "mysql",
host: process.env.TYPEORM_HOST,
port: Number(process.env.TYPEORM_PORT),
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
entities: [path.resolve('src', process.env.TYPEORM_ENTITIES)],
// We are using migrations, synchronize should be set to false.
synchronize: false,
// Run migrations automatically,
// you can disable this if you prefer running migration manually.
migrationsRun: true,
logging: process.env.TYPEORM_LOGGING,
// Allow both start:prod and start:dev to use migrations
// __dirname is either dist or src folder, meaning either
// the compiled js in prod or the ts in dev.
migrations: [path.resolve('src', process.env.TYPEORM_MIGRATIONS)],
cli: {
// Location of migration should be inside src folder
// to be compiled into dist/ folder.
// entitiesDir: process.env.TYPEORM_ENTITIES_DIR,
migrationsDir: path.resolve('src', process.env.TYPEORM_MIGRATIONS_DIR),
// subscribersDir: process.env.TYPEORM_SUBSCRIBERS_DIR,
},
dropSchema: false
};
export = config;
Running console.log(config)
I get:
{
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'myapp',
entities: [ '/var/www/html/myapp/src/**/*.entity{.ts,.js}' ],
synchronize: false,
migrationsRun: true,
logging: 'all',
migrations: [ '/var/www/html/myapp/src/migrations/**/*{.ts,.js}' ],
cli: { migrationsDir: '/var/www/html/myapp/src/migrations' },
dropSchema: false
}
Last but not least.... After spending hours on this issue (making changes to migrations and entities paths, hard-coding values besides getting them from process.env, etc), I tried to execute yarn run typeorm schema:log
(npm run
works as well). I got surprised when I saw that all the content that I expected to be in the migration file I am trying to generate was output to console.
CREATE TABLE `permission_permission` (`id` varchar(36) NOT NULL, `name` varchar(100) NOT NULL, `code` text NOT NULL, `create_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `update_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `delete_date` datetime(6) NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `permission_role` (`id` varchar(36) NOT NULL, `name` varchar(100) NOT NULL, `code` varchar(255) NOT NULL, `create_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `update_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `delete_date` datetime(6) NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `user_user` (`id` varchar(36) NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `is_active` tinyint NOT NULL DEFAULT 0, `create_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `update_date` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `delete_date` datetime(6) NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `permission_role_permission` (`permission_id` varchar(36) NOT NULL, `role_id` varchar(36) NOT NULL, INDEX `IDX_3247040996395a5faea3c9b3a5` (`permission_id`), INDEX `IDX_7d9cfbfd027256ab08658bcf6e` (`role_id`), PRIMARY KEY (`permission_id`, `role_id`)) ENGINE=InnoDB;
CREATE TABLE `user_user_role` (`role_id` varchar(36) NOT NULL, `user_id` varchar(36) NOT NULL, INDEX `IDX_c0c2bbb31e8e8708efc6dd5a64` (`role_id`), INDEX `IDX_beb8c39c852f4d132ba44b483c` (`user_id`), PRIMARY KEY (`role_id`, `user_id`)) ENGINE=InnoDB;
ALTER TABLE `permission_role_permission` ADD CONSTRAINT `FK_3247040996395a5faea3c9b3a54` FOREIGN KEY (`permission_id`) REFERENCES `permission_role`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE `permission_role_permission` ADD CONSTRAINT `FK_7d9cfbfd027256ab08658bcf6e1` FOREIGN KEY (`role_id`) REFERENCES `permission_permission`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE `user_user_role` ADD CONSTRAINT `FK_c0c2bbb31e8e8708efc6dd5a64b` FOREIGN KEY (`role_id`) REFERENCES `user_user`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE `user_user_role` ADD CONSTRAINT `FK_beb8c39c852f4d132ba44b483c0` FOREIGN KEY (`user_id`) REFERENCES `permission_role`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
Can anyone tell me why is schema:log
detecting the changes in my entities, but migration:generate
is not working?
For me this hint helped. Just run npm run build
before generating with npm run typeorm -- migration:generate -n migration_name
the new migration. Somehow an up to date dist
folder needs to be present.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With