Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.3.0 generate migrations path #8762

Closed
Spimy opened this issue Mar 18, 2022 · 30 comments · Fixed by #8764
Closed

0.3.0 generate migrations path #8762

Spimy opened this issue Mar 18, 2022 · 30 comments · Fixed by #8764
Labels

Comments

@Spimy
Copy link

Spimy commented Mar 18, 2022

Issue Description

Expected Behavior

When running migration:generate, I expect the migration generated goes into the migrations path set in the parameter of the DataSource constructor.

Basically, I expect it to generate a migration into the path: E:\Projects\Discord Bots\commissions\luigical\src\migrations\<the_migration_file_here>.ts

Actual Behavior

Generating and creating migrations works but it goes into project root folder.

$ yarn typeorm:generate CreateGuildTable
yarn run v1.22.17
$ yarn typeorm:cli migration:generate -d src/ormconfig.ts CreateGuildTable
$ ts-node ./node_modules/typeorm/cli.js migration:generate -d src/ormconfig.ts CreateGuildTable
Migration E:\Projects\Discord Bots\commissions\luigical\CreateGuildTable.ts has been generated successfully.
Done in 9.21s.

Steps to Reproduce

  1. Use the code below
  2. Create an entity schema in the path project\src\entities\table-name.entity.ts
  3. Run the migration:generate command - in my case the scripts I used are:
"typeorm:cli": "ts-node ./node_modules/typeorm/cli.js",
"typeorm:generate": "yarn typeorm:cli migration:generate -d src/ormconfig.ts",
  1. It does not generate the migration in the correct path
const config: DataSourceOptions = {
  type: 'mysql',
  host: process.env.MYSQL_HOST,
  port: Number(process.env.MYSQL_PORT) || 3306,
  username: process.env.MYSQL_USERNAME,
  password: process.env.MYSQL_PASSWORD,
  database: process.env.MYSQL_DATABASE_NAME,
  entities: [__dirname + '\\entities\\**\\*{.ts,.js}'],
  migrations: [__dirname + '\\migrations\\**\\*{.ts,.js}'],
  cli: {
    migrationsDir: 'src\\migrations',
    entitiesDir: 'src\\entities'
  },
  synchronize: false
};

export const dataSource = new DataSource(config);

My Environment

Dependency Version
Operating System Windows 10 Home
Node.js version 17.3.0
Typescript version 4.5.5
TypeORM version 0.3.0

Additional Context

Relevant Database Driver(s)

DB Type Reproducible
aurora-mysql no
aurora-postgres no
better-sqlite3 no
cockroachdb no
cordova no
expo no
mongodb no
mysql yes
nativescript no
oracle no
postgres no
react-native no
sap no
sqlite no
sqlite-abstract no
sqljs no
sqlserver no

Are you willing to resolve this issue by submitting a Pull Request?

  • ✖️ Yes, I have the time, and I know how to start.
  • ✖️ Yes, I have the time, but I don't know how to start. I would need guidance.
  • ✖️ No, I don’t have the time, but I can support (using donations) development.
  • ✅ No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.
@pleerock
Copy link
Member

You need to specify full path now. cli must be removed from DataSourceOptions (it was documented as a breaking change, but we forgot to remove it from the code). I'll submit a PR, and you need to remove cli from your side. Thanks for the report.

@Matheusagostinho
Copy link

-d option is not working either

@ricardo85x
Copy link

There is no -d option
You should add the full path:
yarn typeorm migration:create src/database/migrations/CreateCategories

@Spimy
Copy link
Author

Spimy commented Mar 24, 2022

-d option is not working either

You should specify the file where you exported your data source object with the -d option and then specify your full path.
For example:

typeorm migration:generate -d <path_to_data_source>/datasource.ts <path_to_migrations_folder>/MigrationName.ts

@pleerock
Copy link
Member

would really appreciate if someone submit a PR with updates in the documentation.

@cyril-git-h
Copy link

You need to specify full path now

what the hell? it's exhausting and not convenient at all. How to configure path once? you should've thought about it. And please update documentation, it's confusing.

@cyril-git-h
Copy link

cyril-git-h commented May 24, 2022

Ok, if someone will be here with that question I created two scripts for package.json

"migration:create": "cd src/migrations && npx typeorm-ts-node-commonjs migration:create",
 "migration:generate": "cd src/migrations && npx typeorm-ts-node-commonjs migration:generate -d ../dataSourceConfig.ts",

so you don't have to write all that stuff everytime

@jkalberer
Copy link

You need to specify full path now. cli must be removed from DataSourceOptions (it was documented as a breaking change, but we forgot to remove it from the code). I'll submit a PR, and you need to remove cli from your side. Thanks for the report.

@pleerock this breaking change is not a great direction. It completely breaks our workflows without a good workaround.

We use .env files for our configuration and generate the DataSourceOptions at runtime (we have many environments and pull keys from a secrets store).
It seems like you no longer allow using the .env for these variables and depend on an actual data-source file.

How can we work around this?

@ryanoboril
Copy link

You need to specify full path now.

@pleerock absolutely ridiculous change

@mlandisbqs
Copy link

@jkalberer -- just stumbled on this thread after scraping against version 3 breaking changes. We do the same as you with .env files and a ConfigService wrapper for dotenv. I don't have a solution for the full path when generating migrations, but we are able to generate a datasource that re-uses the typeorm options that the app uses. I added a file with the following in it:

src/libs/typeorm/datasource.ts

// ... (construct configService and logger first...)
const datasource = new DataSource(getDataSourceOptions(configService, logger, '/services/'));

/**
 * This is for typeorm CLI so it can be passed -d [.../datasource.js] (see package.json)
 */
export default datasource;

...then the options are handled like this...

src/libs/typeorm/typeorm-options.ts

export function getDataSourceOptions(
  configService: ConfigService,
  logger: LoggerService,
  entitiesPath: string
): DataSourceOptions {
  return {
    type: configService.getString('TYPEORM_CONNECTION') as 'postgres',
    host: configService.getString('TYPEORM_HOST'),
    port: configService.getNumber('TYPEORM_PORT'),
    database: configService.getString('TYPEORM_DATABASE'),
    username: configService.getString('TYPEORM_USERNAME'),
    password: configService.getString('TYPEORM_PASSWORD'),
    entities: [__dirname + '/../..' + entitiesPath + configService.getString('TYPEORM_ENTITIES_APP')],
    synchronize: configService.getBoolean('TYPEORM_SYNCHRONIZE'),
    logger: new TypeOrmLogger(configService, logger),
    extra: {
      max: configService.getNumber('TYPEORM_POOL_SIZE_MAX')
    },
    connectTimeoutMS: configService.getNumber('TYPEORM_CONNECT_TIMEOUT_MS'),
    logNotifications: configService.getBoolean('TYPEORM_LOG_NOTIFICATIONS'),
    migrations: [__dirname + '/../../../' + configService.getString('TYPEORM_MIGRATIONS')],
    poolErrorHandler
  };
}

// following function is for NestJS bootstrapping...
export function getTypeOrmModuleOptionsFactory(
  configService: ConfigService,
  logger: LoggerService,
  entitiesPath: string
): (...args: any[]) => Promise<TypeOrmModuleOptions> {
  return async () => getDataSourceOptions(configService, logger, entitiesPath);
}

package.json

    "typeorm:gen": "run-s build:clean build:dist build:pkg \"typeorm migration:run\" \"typeorm migration:generate -- {1} {2}\" --",
    "typeorm:migrate": "run-s \"typeorm migration:run\"",
    "typeorm:revert": "run-s \"typeorm migration:revert\"",
    "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js -d dist/libs/typeorm/datasource.js",

The CLI commands in package.json get passed the datasource, and the NestJS app(s) uses the factory function. All the actual config values are handled in .env files and our ConfigService wrapper.

@DanielMenke
Copy link

Why? This makes everything much more cumbersome.

@jkalberer
Copy link

jkalberer commented Jul 28, 2022

@mlandisbqs - yeah, that's the pattern I settled on. It's definitely a lot less convenient

Why? This makes everything much more cumbersome.

@DanielMenke who are you asking?

@DanielMenke
Copy link

@jkalberer nobody specific. Just wanted to know the intentions behind this invasive change.

@mlandisbqs
Copy link

@DanielMenke -- not sure if this is what you are asking... but my theory as to why the path is now required on the CLI is that the configuration for finding migrations takes an array so it can't be used to generate migrations without knowing which entry to use. @pleerock could maybe confirm this.

@andersonqi
Copy link

Is it a good option to continue in version 0.2.x?

@ngtrdai197
Copy link

@mlandisbqs Can you provide a mini-repo about setting up?

@crazyoptimist
Copy link

Example setup here, if it can help someone stuck in there..

@icrotz
Copy link

icrotz commented Oct 7, 2022

@pleerock Why did you change the workflow without notifying anyone ? This breaking change make everything more complex without any explained reason, it's just non-sense

@tin-pham
Copy link

tin-pham commented Oct 14, 2022

It made me entire 3 day to get to this issue post, I was completely lost it. Thanks, because everyone seem have the same problem
Firstly, why there are datasource for cli, why not just using orm config, we can't even copy the config object to datasource because missing property, it make me feel bad to write the same object name it difference thing, maybe i will link this post to that codebase
Secondly, why remove cli property and directly specify it in package.json, ugly as hell.

@dmastag
Copy link

dmastag commented Oct 16, 2022

Posting my Solution to help anyone who wondered how to :

  • Send variables through the CLI
  • Using cross-var so that it works on Windows also

I have put my datasource inside the orm.config.ts file which uses environment variabels also.

"typeorm": "ts-node --project ./setup/typeorm/tsconfig.json -r tsconfig-paths/register ./setup/typeorm/typeorm.custom-cli.ts",
"typeorm:migration:generate": "cross-var npm run typeorm -- -d setup/typeorm/orm.config.ts migration:generate setup/typeorm/migrations/$npm_config_name",
"typeorm:migration:create": "cross-var npm run typeorm -- migration:create setup/typeorm/migrations/$npm_config_name",
"typeorm:migration:run": "cross-var npm run typeorm -- -d setup/typeorm/orm.config.ts migration:run",
"typeorm:migration:revert": "cross-var npm run typeorm -- -d setup/typeorm/orm.config.ts migration:revert"

If I need to generate a Migration I simple just run
npm run typeorm:migration:generate --name=migration-name

Some notes because I am using an nx workspace with NestJS

  • I am using a custom tsconfig.json that has "module": "commonjs"
  • I am using a custom typeorm.custom-cli.json so the datasource can compile

Hope this helps anyone with the same use-case

@andreghisleni
Copy link

andreghisleni commented Oct 19, 2022

Hello, in my application i have two databases and i used many times -c to specify the configuration on ormconfig.json, but after updating to 0.3.10 I was having the same problem with the CLI. after 3 days searching about the new cli, I created simple cli, in this case i use just migrations. This is my solution to the cli, cli.ts.

/* eslint-disable no-console */

import { exec } from 'child_process';
import minimist from 'minimist'; // eslint-disable-line import/no-extraneous-dependencies

const argv = minimist(process.argv.slice(2));

const option = argv._[0];
const config = argv.c === 'company' ? 'base' : 'general';
const dataSource = argv.d || './src/shared/infra/typeorm/dataSource.ts';
const name = argv.n || 'undefined';

if (!option) {
  console.log(
    'Please, choose an option: \n - migration:create\n - migration:run\n - migration:revert\n - migration:show',
  );
  process.exit(0);
}
if (option === 'migration:create') {
  exec(
    `yarn typeorm-ts-node-esm migration:create ./src/shared/infra/typeorm/migrations/${config}/${name}`,
    (_err, stdout, stderr) => {
      console.log(`${stdout}`);
      console.log(`${stderr}`);
    },
  );
} else {
  exec(
    `yarn typeorm-ts-node-esm ${option} --dataSource=${dataSource}`,
    (_err, stdout, stderr) => {
      console.log(`${stdout}`);
      console.log(`${stderr}`);
    },
  );
}

And in package.json:

...,
"scripts": {
   ...,
    "typeorm": "ts-node -r tsconfig-paths/register ./src/shared/infra/typeorm/utils/cli.ts",
    ...
  },
...

Finally, to use

yarn typeorm migration:create -c company -n Test
yarn typeorm migration:run

@icrotz
Copy link

icrotz commented Oct 20, 2022

Hello, in my application i have two databases and i used many times -c to specify the configuration on ormconfig.json, but after updating to 0.3.10 I was having the same problem with the CLI. after 3 days searching about the new cli, I created simple cli, in this case i use just migrations. This is my solution to the cli, cli.ts.

/* eslint-disable no-console */

import { exec } from 'child_process';
import minimist from 'minimist'; // eslint-disable-line import/no-extraneous-dependencies

const argv = minimist(process.argv.slice(2));

const option = argv._[0];
const config = argv.c === 'company' ? 'base' : 'general';
const dataSource = argv.d || './src/shared/infra/typeorm/dataSource.ts';
const name = argv.n || 'undefined';

if (!option) {
  console.log(
    'Please, choose an option: \n - migration:create\n - migration:run\n - migration:revert\n - migration:show',
  );
  process.exit(0);
}
if (option === 'migration:create') {
  exec(
    `yarn typeorm-ts-node-esm migration:create ./src/shared/infra/typeorm/migrations/${config}/${name}`,
    (_err, stdout, stderr) => {
      console.log(`${stdout}`);
      console.log(`${stderr}`);
    },
  );
} else {
  exec(
    `yarn typeorm-ts-node-esm ${option} --dataSource=${dataSource}`,
    (_err, stdout, stderr) => {
      console.log(`${stdout}`);
      console.log(`${stderr}`);
    },
  );
}

And in package.json:

...,
"scripts": {
   ...,
    "typeorm": "ts-node -r tsconfig-paths/register ./src/shared/infra/typeorm/utils/cli.ts",
    ...
  },
...

Finally, to use

yarn typeorm migration:create -c company -n Test
yarn typeorm migration:run

Thanks for sharing, but the fact that we have to implement a CLI on our end seem a little bit shaky

@FerhatSaritas
Copy link

Hello

Is this still the only solution at the moment? And does typeorm support typescript files for the cli? I heard that it currently only supports js files.

@sadhakbj
Copy link

Why this kind of nonsense and breaking changes?

@guilhermekodenvis
Copy link

You guys have a grate tool. TypeORM is really nice. But this kind of thing is not great. It doesn't seem really finished. Following the documentation this kind of error is happening all time. Thanks for support.

@g1coder
Copy link

g1coder commented Mar 30, 2023

hello, guys! Are you going to fix this issues?

@sadhakbj
Copy link

sadhakbj commented Mar 31, 2023

@g1coder
I worked on a hack since there was no concrete solution provided by typeorm.

Taken from part of my medium article: https://sadhakbj.medium.com/lets-create-fully-dockerized-nodejs-backend-application-with-express-js-typescript-typeorm-and-1f7396623301

We want to create migrations using the CLI, but the latest version of typeorm has some breaking changes, so we need to take advantage of the package: yargs . Create a folder called scripts on the root directory and create a file: migration-create.js with following contents:

#!/usr/bin/env node

const yargs = require("yargs");
const { execSync } = require("child_process");

// Parse the command-line arguments
const {
  _: [name],
  path,
} = yargs.argv;

// Construct the migration path
const migrationPath = `src/database/migrations/${name}`;

// Run the typeorm command
execSync(`typeorm migration:create ${migrationPath}`, { stdio: "inherit" });

Now let’s update our package.json to include the scripts to create new migration, show the list of the migrations and revert it:

 "scripts": {
    "build": "tsc",
    "dev": "nodemon --watch src --exec 'ts-node' src/index.ts",
    "start": "node dist/index.js",
    "typeorm": "typeorm-ts-node-commonjs -d src/database/data-source.ts",
    "migration:show": "yarn typeorm migration:show",
    "migration:create": "node scripts/migration-create.js",
    "migration:revert": "yarn typeorm migration:revert"
  }

With this we can run the command: yarn migration:create CreateAuthorsTable

@neew-gen
Copy link

neew-gen commented Apr 8, 2023

@g1coder I worked on a hack since there was no concrete solution provided by typeorm.

Taken from part of my medium article: https://sadhakbj.medium.com/lets-create-fully-dockerized-nodejs-backend-application-with-express-js-typescript-typeorm-and-1f7396623301

We want to create migrations using the CLI, but the latest version of typeorm has some breaking changes, so we need to take advantage of the package: yargs . Create a folder called scripts on the root directory and create a file: migration-create.js with following contents:

#!/usr/bin/env node

const yargs = require("yargs");
const { execSync } = require("child_process");

// Parse the command-line arguments
const {
  _: [name],
  path,
} = yargs.argv;

// Construct the migration path
const migrationPath = `src/database/migrations/${name}`;

// Run the typeorm command
execSync(`typeorm migration:create ${migrationPath}`, { stdio: "inherit" });

Now let’s update our package.json to include the scripts to create new migration, show the list of the migrations and revert it:

 "scripts": {
    "build": "tsc",
    "dev": "nodemon --watch src --exec 'ts-node' src/index.ts",
    "start": "node dist/index.js",
    "typeorm": "typeorm-ts-node-commonjs -d src/database/data-source.ts",
    "migration:show": "yarn typeorm migration:show",
    "migration:create": "node scripts/migration-create.js",
    "migration:revert": "yarn typeorm migration:revert"
  }

With this we can run the command: yarn migration:create CreateAuthorsTable

Thank you so mush. It is just working. Magic

@matheusalxds
Copy link

cd src/migrations && npx typeorm-ts-node-commonjs migration:generate -d ../dataSourceConfig.ts

It works! 😄

@AlmazHecker
Copy link

AlmazHecker commented Oct 2, 2023

Just discovered that when you specify name for migration you can also specify full path:
ts-node -r tsconfig-paths/register node_modules/typeorm/cli.js migration:generate migrations/EntityMigration -d ormconfig.ts

this script will generate migration in ./migrations folder

ormconfig.ts is adatasource configuration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.