TypeORM Migration: File must contain a TypeScript / JavaScript code and export a DataSource instance

Viewed 7784

When trying to autogenerate migrations I get the following error.

File must contain a TypeScript / JavaScript code and export a DataSource instance

This is the command that I am running:

typeorm migration:generate projects/core/migrations/user -d db_config.ts -o

And my db_config.ts file looks like this:

import { DataSource } from "typeorm";

const AppDataSource = new DataSource({
  type: "postgres",
  host: process.env.PGHOST,
  port: 5432,
  username: process.env.PGUSER,
  password: process.env.PGPASSWORD,
  database: process.env.PGDATABASE,
  entities: ["./projects/**/entities/*.ts"],
  migrations: ["./projects/**/migrations/**.js"],
  synchronize: true,
  logging: false,
}); 

export default AppDataSource

My current file structure looks like this:

  • back_end -- projects --- index.ts --- db_config.ts

And my index.ts file looks like this:

import express from "express";
import { AppDataSource } from "./data-source";
import budget_app from "./projects/budget_app/routes";

export const app = express();
const port = 3000;

AppDataSource.initialize()
  .then(() => {
    console.log("Data Source has been initialized!");
  })
  .catch((err) => {
    console.error("Error during Data Source initialization", err);
  });

// export default AppDataSource;

app.get("/", (req, res) => {
  res.send("Hello World!!!!");
});

app.use("/budget_app", budget_app);

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

I am also running this in a docker container along with my postgres database. I have confirmed that the connection works because if I do synchronize=true it will create the table just fine. I just can't create the migration.

So I'm confused and don't know where to go from here to fix the issue. Thanks for your help in advance!

5 Answers

I was running into the same issues (typeorm 0.3.4). I was just using npx typeorm migration:show -d ./src/data-source.ts and getting the same error as above (File must contain a TypeScript / JavaScript code and export a DataSource instance), while generating the migration file itself worked somehow, but not running/showing the migrations themselves.
My datasource looks like this

export const AppDataSource = new DataSource({
  type: 'postgres',
  url: process.env.DATABASE_URL,
  logging: true,
  entities: ['dist/entities/*.js'],
  migrations: ['dist/migrations/*.js'],
});

because my tsc output lives in /dist. So based on the comments above I started using the datasource file that was generated from TypeScript and the error message changed:

npx typeorm migration:run -d ./dist/appDataSource.js
CannotExecuteNotConnectedError: Cannot execute operation on "default" connection because connection is not yet established.

So I looked into the database logs and realized it wanted to connect to postgres with the standard unix user, it wasn't honoring the connection strings in the datasource code. I had to supply all environment variables to the command as well and it worked: DATABASE_URL=postgresql://postgres:postgres@localhost:5432/tsgraphqlserver npx typeorm migration:run -d ./dist/appDataSource.js

I had the same issue when using a .env file (if you don't have a .env file, this answer probably is irrelevant for you).

It seems, that the CLI does not pick environment variables from dotenv, so you have to load them yourself. E.g., using dotenv library, put this on top of your data-source file:

import * as dotenv from 'dotenv';

dotenv.config();

// export const AppDataSource = new DataSource()...

Alternatively, provide real environment variables when running the script:

PGHOST=... PGUSER=... PGDATABASE=... PGPASSWORD=... typeorm migration:generate ...

Add the following to package.json scripts section:

      "typeorm": "typeorm-ts-node-commonjs",
      "migration:run": "ts-node ./node_modules/typeorm/cli.js migration:run -d ./src/data-source.ts",
      "schema:sync": "npm run typeorm schema:sync -- -d src/data-source.ts",
      "migration:show": "npm run typeorm migration:show -- -d src/data-source.ts",
      "migration:generate": "npm run typeorm migration:generate -- -d src/data-source.ts",
      "migration:create": "npm run typeorm migration:create"

You can then use npm run migration:create -- src/migration for example

I had trouble with migrations in typeorm, and finally found a solution that will work consistently. For me, build and then using js datasource didn't work, So i provide my solution for those who steel have struggle with typeorm-migrations.

Here is my step by step solution:

  1. create your datasource config in some file like datasource.config.ts,

    mine is like this:

      import * as mysqlDriver from 'mysql2';
      import {DataSourceOptions} from 'typeorm';
      import dotenv from 'dotenv';
    
      dotenv.config();      
    
      export function getConfig() {
       return {
        driver: mysqlDriver,
        type: 'mysql',
        host: process.env.MYSQL_HOST,
        port: parseInt(process.env.MYSQL_PORT, 10),
        username: process.env.MYSQL_USER,
        password: process.env.MYSQL_PASSWORD,
        database: process.env.MYSQL_DB,
        synchronize: false,
        migrations: [__dirname + '/../../typeorm-migrations/*.{ts,js}'],
        entities: [__dirname + '/../**/entity/*.{ts,js}'],
    } as DataSourceOptions;
    

}

  1. create a file with name like migration.config.ts

    the implementation is like this:

     const datasource = new DataSource(getConfig()); // config is one that is defined in datasource.config.ts file
     datasource.initialize();
     export default datasource; 
    
    
  2. now you can define your migration commands in package.json file

  "migration:up": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm migration:run -d config/migration.config.ts",
  "migration:down": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm migration:revert -d config/migration.config.ts"

with running yarn run migration:up you will be able to run your defined migrations in typeorm-migrations folder

I am actually running into the same issue.

I was able to resolve it by using *.js instead of *.ts

Please try something like this:

tsc && typeorm migration:generate -d db_config.ts projects/core/migrations/user

My tsconfig.json looks like this.

{
    "compilerOptions": {
      "target": "esnext",
      "module": "CommonJS",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "outDir": "./build",
      "removeComments": false,
      "resolveJsonModule": true,
      "esModuleInterop": true,
    }
  }

I recommend you open an issue on the typeorm github repo, I think it might be a bug.

Related