GithubHelp home page GithubHelp logo

w3tecch / typeorm-seeding Goto Github PK

View Code? Open in Web Editor NEW
870.0 17.0 132.0 1.22 MB

๐ŸŒฑ A delightful way to seed test data into your database.

Home Page: https://www.npmjs.com/package/typeorm-seeding

License: MIT License

JavaScript 6.89% TypeScript 93.11%
typeorm-extension typescript cli seed database seeding data-seeding typeorm

typeorm-seeding's People

Contributors

buuug7 avatar clovis1122 avatar davicedraz avatar dennisameling avatar dependabot[bot] avatar eugenio165 avatar jesster2k10 avatar jleck avatar jorgebodega avatar jthodge avatar mkorobkov avatar oroce avatar owonwo avatar raphaelwoude avatar semantic-release-bot avatar sfelix-martins avatar stephane-rbn avatar vologab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typeorm-seeding's Issues

Seed not working with BeforeInsert decorator

I created a user seed that will insert a new user with a hashed password. On my user.entity.ts, I have a @BeforeInsert decorator to hash the password before inserting it into the DB. This works when calling the API endpoint but wasn't triggered when using typeorm-seeding. It will only insert the password as plain text.

user.seed.ts

import { Connection } from 'typeorm';
import { User } from '../model/user.entity';

export default class CreateUser implements Seeder {
  public async run(factory: Factory, connection: Connection): Promise<any> {
    await connection
      .createQueryBuilder()
      .insert()
      .into(User)
      .values([
        {
          name: 'Admin',
          email: '[email protected]',
          company: 'Admin Ltd.',
          password: 'test123'
        }
      ])
      .execute()
  }
}

user.entity.ts

  Entity, 
  Column, 
  Generated, 
  OneToOne, 
  BeforeInsert, 
} from 'typeorm';
import { BaseEntity } from './base.entity';
import { UserRole } from './user-role.entity';
import { ApiProperty } from '@nestjs/swagger';
import { CrudValidationGroups } from '@nestjsx/crud';
import * as bcrypt from 'bcryptjs';
import { 
  IsOptional, 
  IsNotEmpty, 
  IsString, 
  MaxLength, 
  IsEmail 
} from 'class-validator';

const { CREATE, UPDATE } = CrudValidationGroups;

@Entity('users')
export class User extends BaseEntity {
  @IsOptional({ groups: [UPDATE] })
  @IsNotEmpty({ groups: [CREATE] })
  @IsString({ always: true })
  @MaxLength(100, { always: true })
  @Column({ type: 'varchar', length: 100, nullable: false })
  name: string;

  @IsOptional({ groups: [UPDATE] })
  @IsNotEmpty({ groups: [CREATE] })
  @IsEmail()
  @IsString({ always: true })
  @MaxLength(100, { always: true })
  @Column({ type: 'varchar', length: 100, nullable: false, unique: true })
  email: string;

  @IsString({ always: true })
  @MaxLength(100, { always: true })
  @Column({ type: 'varchar', length: 100, nullable: true })
  company: string;

  @Column({ type: 'varchar', length: 100, nullable: false })
  password: string;

  @BeforeInsert()
  async setPassword(password: string) {
    const salt = await bcrypt.genSalt();
    this.password = await bcrypt.hash(password || this.password, salt);
  }

  async checkPassword(plainPassword: string) {
    return await bcrypt.compare(plainPassword, this.password);
  }
}

Module aliases are not resolved

Getting error: Error: Cannot find module '{alias}/{path}', even with alias paths defined in tsconfig.json. typeorm cli works fine with same settings and running the command with ts-node.

I am quite new to typescript, else would have tried to fix it, opening a PR.

Does not work with `export default`

I have a config file called dev_seed.ts and inside it:

export default {
  ...
  seeds: ['db/seed/**/*.seed.ts'],
  factories: ['db/factory/**/*.factory.ts'],
};

This does not work when running command:
"seed": "ts-node-dev ./node_modules/typeorm-seeding/dist/cli.js seed --config /db/seed/config/dev_seed.ts"

Where as this code with same command does work:

module.exports = {
  ...
  seeds: ['db/seed/**/*.seed.ts'],
  factories: ['db/factory/**/*.factory.ts'],
};

Pass open connection?

Hey there,

Looking to see if there is a way to use an existing connection. While using in tests in a nestjs app I have a case like this ->

beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({ isGlobal: true }),
        MyTestModule,
        TypeOrmModule.forRoot({
          type: 'postgres',
          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,
          logging: false,
          entities: ['src/**/*.entity{.ts,.js}'],
          synchronize: false,
        }),
      ],
    }).compile()
    app = module.createNestApplication()
    await app.init()

    // Is it possible to use the connection 'default' created by the test application
    await useRefreshDatabase()
  })

Basically looking to avoid AlreadyHasActiveConnectionError: Cannot create a new connection named "default", because connection with such name already exist and it now has an active connection session.

Is there a way to use an existing connection, or do I just need to make a new one for typeorm-seeding? If so where would I specify a name for that.

TypeError: clazz is not a constructor

I just encountered the error in the title. My code looks like this:

  • entities/User.ts:
import { Entity, PrimaryColumn, Column, BaseEntity, BeforeInsert, BeforeUpdate } from "typeorm";
import bcrypt from "bcrypt";

const saltRounds = 10;
@Entity({ name: "users" })
export class User extends BaseEntity {
  @PrimaryColumn()
  username: string;

  @Column()
  password: string;

  @Column()
  fullname: string;

  @Column({ name: "profile_picture" })
  profilePicture: string;

  @Column()
  birthdate: Date;

  @Column()
  gender: string;

  @Column()
  email: string;

  @Column()
  phone: string;

  @Column()
  address: string;

  @Column({ name: "is_admin" })
  isAdmin: boolean;

  strip() {
    this.username = this.username.trim();
    this.password = this.password.trim();
  }

  @BeforeUpdate()
  @BeforeInsert()
  async encryptPassword() {
    this.password = await bcrypt.hash(this.password, saltRounds);
  }
}

export const DUMMY_USERS = [
  {
    username: "john",
    password: "123",
    fullname: "john",
    profilePicture:
      "https://lh3.googleusercontent.com/a-/AOh14Gi0DgItGDTATTFV6lPiVrqtja6RZ_qrY91zg42o-g",
    birthdate: new Date("1999-11-25"),
    gender: "male",
    email: "[email protected]",
    phone: "0123456789",
    address: "somewhere on this earth"
  }
];
  • seeders/users.seed.ts:
import { Seeder } from "typeorm-seeding";
import { Connection } from "typeorm";
import { User, DUMMY_USERS } from "../entities/User";

export default class UserSeeder implements Seeder {
  public async run(_, connection: Connection): Promise<void> {
    await connection.createQueryBuilder().insert().into(User).values(DUMMY_USERS).execute();
  }
}
  • ormconfig.json:
{
  "type": "postgres",
  "host": "localhost",
  "port": 5432,
  "username": "***",
  "password": "***",
  "database": "***",
  "logging": true,
  "entities": ["build/entities/*.js"],
  "migrations": ["build/migrations/*.js"],
  "seeds": ["server/seeders/*.ts"],
  "cli": {
    "migrationsDir": "server/migrations"
  }
}

The full logs:

yarn run v1.22.4
$ ts-node ./node_modules/typeorm-seeding/dist/cli.js seed
๐ŸŒฑ  TypeORM Seeding v1.6.1
โœ” ORM Config loaded
โœ” Factories are imported
โœ” Seeders are imported
โœ” Database connected
โœ– Could not run the seed undefined!
TypeError: clazz is not a constructor
    at /home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/typeorm-seeding/src/typeorm-seeding.ts:44:26
    at step (/home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/tslib/tslib.js:141:27)
    at Object.next (/home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/tslib/tslib.js:122:57)
    at /home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/tslib/tslib.js:115:75
    at new Promise (<anonymous>)
    at Object.__awaiter (/home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/tslib/tslib.js:111:16)
    at Object.exports.runSeeder (/home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/typeorm-seeding/src/typeorm-seeding.ts:43:57)
    at Object.<anonymous> (/home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/typeorm-seeding/src/commands/seed.command.ts:94:15)
    at step (/home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/tslib/tslib.js:141:27)
    at Object.next (/home/lamnhh/Projects/PTUDW-17TN-Nhom13/node_modules/tslib/tslib.js:122:57)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I looked into the code in importer.ts and see these lines:

export const importSeed = async (filePath: string): Promise<SeederConstructor> => {
  const seedFileObject: { [key: string]: SeederConstructor } = await import(filePath)
  const keys = Object.keys(seedFileObject)
  return seedFileObject[keys[0]]
}

That keys[0] part looks weird to me. I logged keys out on my machine and it gives ["_esModules", "UserSeeder"] so the function returns true, causing runSeeder to run new true() and crashes.

May I ask if the keys[0] part was intentional or not?

Cannot load seeds when `__dirname` is in path

As seen on the TypeOrm documentation, one can use __dirname for the path to entities and stuff.

loadFiles util function, probably due to the use of process.cwd(), doesn't load any seeds if the path is declared as such:

{
  // ormconfig.js
  seeds: [`${__dirname}/seeds/*.js`],
  ...
}

Any input on that ?

How to use define inside a loop?

I am doing this

for (let i = 0; i < results.length; i++) {
  const row = results[i];
  define(MeterEntity, () => {
    const meterEntity = new MeterEntity();
    meterEntity.serial = row["Serial"];
    return meterEntity;
  });
  define(MeterReadingEntity, () => {
    const readingEntityObject = new MeterReadingEntity();
    readingEntityObject.varh = row["VARH"];
    readingEntityObject.wh = row["WH"];
    const dateTimeString: string = row["ReadingDateTimeUTC"];
    const dateTimeUTC = createDate(dateTimeString);
    const date = new Date(dateTimeUTC);
    readingEntityObject.createdAt = date.toISOString();
    readingEntityObject.meter = factory(MeterEntity)() as any;
    return readingEntityObject;
  });
}

where results is an array of objects with all the keys I am accessing in the factory definition.

I later run this factory like this

  public async run(factory: Factory, connection: Connection): Promise<any> {
    if (connection && connection.isConnected) {
      await factory(MeterEntity)().make();
    }
  }
}

I have kept the config of where the seeds and factories live to default and have those folders created in my project as per the defaults docs.

This runs fine. It connects to the db and it finds the seeds and runs them but just always persists the last array entry and never everything in the array.

I would expect define to run through all 100 elements in the array and persist all of them to the db.

Is there something I am missing regarding how this function works?
How can I fix this?

Running a seeder tries to drop foreign keys in multiple tables and fails

I'm using TypeORM with MySQL. For some reason running npm run seed:run with the package.json command suggested in the README results in foreign keys getting dropped from multiple tables, which fails at some point and my data doesn't get seeded at all but my schema is completely borked.

Here is my custom seeder:

import { Factory, Seeder } from 'typeorm-seeding'
import { Connection } from 'typeorm/index'
import { PackageEntity, PackageStyle, PackageType } from '../../vendors/entities/package.entity'

const packages = [
   // some test data here...
]

export default class CreatePackages implements Seeder {
  public async run(factory: Factory, connection: Connection): Promise<any> {
    await connection
      .createQueryBuilder()
      .insert()
      .into(PackageEntity)
      .values(packages.map(pkg => new PackageEntity({
        claim: pkg.claim,
        description: pkg.claim,
        entryType: PackageType[pkg.claim],
        icon: pkg.icon,
        isPublic: pkg.isPublic,
        label: pkg.label,
        price: pkg.price,
        style: PackageStyle[pkg.style],
      })))
      .execute()
  }}

This is what I get when running the seeder.

โ ธ Connecting to the databasequery: SELECT VERSION() AS `version`
query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = 'hp24' AND `TABLE_NAME` = 'typeorm_metadata'
query: ALTER TABLE `contact_infos` DROP FOREIGN KEY `FK_ccbecb4c53bd6bb363e946dba2e`
โ ผ Connecting to the databasequery: ALTER TABLE `vendor_feature_values` DROP FOREIGN KEY `FK_6fc1266afdcaf7c9d520469cc06`
query: ALTER TABLE `vendor_feature_values` DROP FOREIGN KEY `FK_a87f2c41fb59d6f9efc81a2c0eb`
query: ALTER TABLE `reviews` DROP FOREIGN KEY `FK_dc64fb57616462f713cce274519`
query: ALTER TABLE `review_criteria_ratings` DROP FOREIGN KEY `FK_2642fe113c24977dc4e5c3c8486`
query: ALTER TABLE `locations` DROP FOREIGN KEY `FK_cd8e52f4efbd3e906b80e2bea81`
query: ALTER TABLE `vendors` DROP FOREIGN KEY `FK_7486b81eca8501f67dd662cc1b1`
query: ALTER TABLE `gallery_images` DROP FOREIGN KEY `FK_745f62470c59949a750e006fc87`
query: ALTER TABLE `gallery_images` DROP FOREIGN KEY `FK_b30246956cf74a1baa674014b2c`
โ ด Connecting to the databasequery: DROP INDEX `IDX_dc64fb57616462f713cce27451` ON `reviews`
query: DROP INDEX `REL_12a0f887b44bb8a6107c02dbb0` ON `reviews`
query failed: DROP INDEX `REL_12a0f887b44bb8a6107c02dbb0` ON `reviews`
error: Error: ER_DROP_INDEX_FK: Cannot drop index 'REL_12a0f887b44bb8a6107c02dbb0': needed in a foreign key constraint

Why is typeorm-seeding attempting to modify my schema at all? I thought it's supposed to just import data.

FactoryInterface is not found

I'm attempting to use this example:

export default class CreatePets implements Seeder {
  public async run(factory: FactoryInterface, connection: Connection): Promise<any> {
    const connection = await factory.getConnection()
    const em = connection.createEntityManager()

    await times(10, async n => {
      // This creates a pet in the database
      const pet = await factory(Pet)().create()
      // This only returns a entity with fake data
      const user = await factory(User)({ roles: ['admin'] }).make()
      user.pets = [pet]
      await em.save(user)
    })
  }
}

But there doesn't appear to be a FactoryInterface nor does the Factory type appear to have .getConnection() on it.

Is this a typo in the README? Or something else?

Use cli without ormconfig file

Is it possible to use the current cli without a ormconfig file? I normally initiate my database connection as follow, this way I can keep all the code on typescript side and avoid having an extra configuration file

import path from 'path';
import { createConnection, Connection } from 'typeorm';

import { env } from './env';

const { DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME } = env;

export const createDbConnection = async (): Promise<Connection> => {
  try {
    const entitiesPath = path.resolve(process.cwd(), 'src/db/entities/*{.ts,.js}');

    return await createConnection({
      type: 'postgres',
      host: DB_HOST,
      port: DB_PORT,
      username: DB_USER,
      password: DB_PASSWORD,
      database: DB_NAME,
      entities: [entitiesPath],
      synchronize: true,
    });
  } catch (e) {
    throw new Error(`Unable to connect with the database, e: ${e.message}`);
  }
};

Factory returns EntityFactory, which is not assignable

I can't understand how relations work for entity factories. Below is the snippet of code from the README (minus some things for readability)

import Faker from 'faker';
import { define } from 'typeorm-seeding';
import { Pet } from '../entities'

define(Pet, (faker: typeof Faker, settings: undefined) => {
  // ...other stuff
  pet.user = factory(User)() // invalid type
  return pet
})

factory(User)() returns an EntityFactory<User, undefined> object, which is not a User type, and thus not assignable to pet.user.

Am I just doing it wrong?

Entity with @Column('simple-array') fails to seed

Some column-types in typeorm are resolving to objects. For example entitites with column-type "simple-array" failing to seed because the following expression is "true":

if (typeof entity[attribute] === 'object' && !(entity[attribute] instanceof Date)) {

and the subentity can't be resolved. These issue is even harder to grasp, because the thrown error says simply "Error: Could not save entity".

[BUG] CLI Options --root doesn't work as expect

According to the doc cli-options shows that if your ormconfig.js is not located at the root of your project, you can use --root (or -r) to tell cli where's the path to the typeorm config file.

Say you have a ormconfig.js file located at src/config, and the folder structure would be this...

  • /src
    • /config
      • ormconfig.js

Then, you should add the option -r src/config to your script...

"seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed -r src/config"

I tried src/config, /src/config, ./src/config

After running this script, I got an error like this...

ๆˆชๅœ– 2020-07-02 ไธŠๅˆ10 24 24

Therefore, the options of --root (or -r) don't seems to work!


I found that some of the users may run into the same error. #63 #75

The temporary fix to the problem is to use --name (or -n) instead of --root (or -r).

"seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed -n src/config/ormconfig.js"

Thanks to @achmadfatoni: #75 (comment)

TypeError: this.subQuery is not a function

I don't really know what I am doing wrong, can you help me?

This is the complete output:

 yarn ts-node -r tsconfig-paths/register ../../node_modules/typeorm-seeding/dist/cli.js seed
yarn run v1.22.0
$ /Volumes/SD/Users/bruno/Projects/corona-down/node_modules/.bin/ts-node -r tsconfig-paths/register ../../node_modules/typeorm-seeding/dist/cli.js seed
๐ŸŒฑ TypeORM Seeding v1.4.4
โœ” ORM Config loaded
โœ” Factories are imported
โœ” Seeders are imported
โœ” Database connected
โœ– Could not run the seed CreateApplicationToken!
TypeError: this.subQuery is not a function
    at InsertQueryBuilder.QueryBuilder.createFromAlias (/Volumes/SD/Users/bruno/Projects/corona-down/src/query-builder/QueryBuilder.ts:551:131)
    at InsertQueryBuilder.into (/Volumes/SD/Users/bruno/Projects/corona-down/src/query-builder/InsertQueryBuilder.ts:158:32)
    at CreateApplicationToken.run (/Volumes/SD/Users/bruno/Projects/corona-down/packages/backend/src/database/seeds/CreateApplicationToken.ts:11:8)
    at /Volumes/SD/Users/bruno/Projects/corona-down/node_modules/typeorm-seeding/src/typeorm-seeding.ts:48:17
    at step (/Volumes/SD/Users/bruno/Projects/corona-down/node_modules/tslib/tslib.js:139:27)
    at Object.next (/Volumes/SD/Users/bruno/Projects/corona-down/node_modules/tslib/tslib.js:120:57)
    at /Volumes/SD/Users/bruno/Projects/corona-down/node_modules/tslib/tslib.js:113:75
    at new Promise (<anonymous>)
    at Object.__awaiter (/Volumes/SD/Users/bruno/Projects/corona-down/node_modules/tslib/tslib.js:109:16)
    at Object.exports.runSeeder (/Volumes/SD/Users/bruno/Projects/corona-down/node_modules/typeorm-seeding/src/typeorm-seeding.ts:46:57)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

This is my seeder:

import { Factory, Seeder } from 'typeorm-seeding';
import { Connection } from 'typeorm';
import { ApplicationToken } from '@backend/entities/ApplicationToken';
import uniqueString = require('unique-string');

export default class CreateApplicationToken implements Seeder {
  public async run(_factory: Factory, connection: Connection): Promise<void> {
    await connection
      .createQueryBuilder()
      .insert()
      .into(ApplicationToken)
      .values([
        { token: uniqueString() },
      ])
      .execute();
  }
}

how to configure where ormconfig.js located

i have ormconfig.js located at src/ormconfig.js

import { ConnectionOptions } from "typeorm";
require("dotenv").config();

const ormConfig: ConnectionOptions = {
  type: "mysql",
  host: process.env.DB_HOST || "127.0.0.1",
  port: Number(process.env.DB_PORT) || 3306,
  username: process.env.DB_USER || "root",
  password: process.env.DB_PASSWORD || "secret",
  database: process.env.DB_NAME || "database",
  synchronize: false,
  logging: false,
  entities: ["build/entity/**/*.js"],
  migrations: ["build/migration/**/*.js"],
  subscribers: ["build/subscriber/**/*.js"],
  cli: {
    entitiesDir: "src/entity",
    migrationsDir: "src/migration",
    subscribersDir: "src/subscriber"
  }
};

export = ormConfig;

in my code i use this config like below:

import app from "./app";
import { PORT } from "./constants/app.constant";
import "reflect-metadata";
import { createConnection } from "typeorm";
import ormConfig from "./config/ormconfig";

createConnection(ormConfig)
  .then(async connection => {
    app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
  })
  .catch(error => console.log(error));

[Bug] Root Param should be respected in OrmConfig file

Dear @hirsch88 ,

today i tried to add your library to my existing project in order to provide respective seeding functionality.

For the context, please note that i use a mono-repository with nrwl/nx. I have a few applications (all stored in apps/ folder of my project root), whereas one is a NestJS API. The latter uses TypeORM with an ormconfig.js file and your library.

However, when i want to run the commands, i have to set the additional --root parameter, because my ormconfig.js file is not stored in the root folder of the mono-repository, but in the specific application folder (e.g., apps/api/src/ormconfig.js).

My apps/api/src/ormconfig.js file looks like this:

module.exports = {
  // ... lots of params to connect to the database
  synchronize: false,
  seeds: ['my/custom/path/to/seeds/*.ts'],
};

However, because i need to call the seeder command with --root param, i expected the seeds parameter to prepend respective root path. For example, the path should be apps/api/src/my/custom/path/to/seeds/*.ts.

Not sure, if i did something wrong, but my seeds were not properly found. If i entered the full path (relative to the root folder of the project itself) it worked out!

All the best

How do I run it?

Hey Guys, I loved your aprroach to seeding a database, and I would really like to use it. So here comes a question that may sound a bit stupid, but I just can't figure out how to do it. How do I run my seeds? I have already defined a factory and a class that implements Seed, but how do I make it work? Thanks in advance.

Seeder Ordering?

How do I control the order in which the seeds are ran, for example when it comes to seeding entities with relations, I assume one seed would have to be ran before the other?

Load seeds from other config file

I'm using Nest.js and dotenv package.
Is it possible to use typeorm-seeding with Nest.js?
My config file is placed here /src/config/database.ts
Thanks.

Cannot read property 'name' of undefined

Hello,

I have a problem with initializing test data

I run this CLI:
"seed:config": "ts-node ./node_modules/typeorm-seeding/dist/cli.js config"

and this
"seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed -n"

And I have this error message:
image

Why ?

My package.json file:
{ "name": "xxxxxxxx", "version": "0.0.1", "description": "Graphql with TypeORM", "private": true, "license": "", "scripts": { "start": "ts-node src/graphql/server.ts", "migrate:create": "ts-node ./node_modules/typeorm/cli.js migrations:create", "migrate:generate": "ts-node ./node_modules/typeorm/cli.js migrations:generate", "migrate:run": "ts-node ./node_modules/typeorm/cli.js migration:run", "schema:drop": "ts-node ./node_modules/typeorm/cli.js schema:drop", "schema:sync": "ts-node ./node_modules/typeorm/cli.js schema:sync", "schema:log": "ts-node ./node_modules/typeorm/cli.js schema:log", "seed:config": "ts-node ./node_modules/typeorm-seeding/dist/cli.js config", "seed:run": "ts-node ./node_modules/typeorm-seeding/dist/cli.js seed -n", "db:setup": "npm run schema:drop && npm run schema:sync && npm run seed:config && npm run seed:run" }, "devDependencies": { "@types/bcryptjs": "^2.4.2", "@types/express": "^4.17.6", "@types/express-session": "^1.17.0", "@types/faker": "^4.1.12", "@types/lodash": "^4.14.153", "@types/node": "^14.0.5", "prettier": "^2.0.5", "ts-node": "^8.10.1", "typescript": "^3.9.3" }, "dependencies": { "@types/express": "^4.17.6", "apollo-server-express": "^2.14.0", "bcryptjs": "^2.4.3", "class-validator": "^0.12.2", "express": "^4.17.1", "express-session": "^1.17.1", "graphql": "^15.0.0", "lodash": "^4.17.15", "mysql": "^2.18.1", "reflect-metadata": "^0.1.13", "typeorm": "^0.2.25", "typeorm-seeding": "^1.6.1" } }

My ormconfig.json file:
[ { "name": "default", "type": "mysql", "host": "localhost", "port": 3306, "username": "admin", "password": "admin", "database": "mydb", "synchronize": true, "logging": true, "logger": "file", "entityPrefix": "", "entities": ["src/db/entity/**/*.ts"], "migrations": ["src/db/migration/**/*.ts"], "subscribers": ["src/db/subscriber/**/*.ts"], "factories": ["src/db/factories/**/*.ts"], "seeds": ["src/db/seeds/**/*.ts"], "cli": { "entitiesDir": "src/db/entity", "migrationsDir": "src/db/migration", "subscribersDir": "src/db/subscriber", "factoriesDir": "src/db/factories", "seedsDir": "src/db/seeds" } } ]

My tsconfig.json file:
{ "compilerOptions": { "lib": ["dom", "es6", "es2017", "esnext.asynciterable"], "target": "es5", "module": "commonjs", "sourceMap": true, "moduleResolution": "node", "outDir": "./build", "removeComments": true, "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "noImplicitThis": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "allowSyntheticDefaultImports": false, "emitDecoratorMetadata": true, "experimentalDecorators": true }, "exclude": ["node_modules"], "include": ["./src/**/*.tsx", "./src/**/*.ts"] }

README is outdated

The README seems to be outdated. The seeder examples still extends Seed rather than Seeder and uses the seed method rather than run. I think this should be updated as it seems to be a bit confusing.

I could send a PR to update it

Usage for unit testing

First of all, thanks for the awesome lib!

I was wondering if there's some way of using the factories to seed specific data for unit testing.

README has wrong .env configs

Just started using the package on a personal project, and couldn't make the seeds run. I was getting some "Cannot read property 'name' of undefined", so I jumped into the source code, to try and find the error. It comes from what the README states about settings the ".env" configs:

or add the following variables to your .env file.
TYPEORM_SEEDING_FACTORIES=src/seeds/**/*{.ts,.js} TYPEORM_SEEDING_SEEDS=src/factories/**/*{.ts,.js}

As you might noticed, the paths are inverted to the actual feature it should belong to, so src/seeds is used for Factories, and src/factories is used for Seeds.

import { define } from 'typeorm-seeding'; Error

Hi @hirsch88 Awesome update, trying to make it work with my project but I get the following mysterious error!

import { define } from 'typeorm-seeding';
ย ย ย ย ย ย ย ย ย ย ย  ^
SyntaxError: Unexpected token

This is what my code looks like

import * as Faker from 'faker';
import { define } from 'typeorm-seeding';
import * as uuid from 'uuid';

import { Booking } from '../entities/Booking';

define(Booking, (faker: typeof Faker, settings: { role: string } | undefined ) => {
// tslint:disable-next-line: no-console
    console.log(settings);
    const gender = faker.random.number(1);
    const title = faker.name.firstName(gender);
    const lastName = faker.name.lastName(gender);
    const email = faker.internet.email(title, lastName);
    // const username = faker.internet.userName(title, lastName);
    const booking = new Booking();
    booking.id = uuid.v1();
    booking.title = title;
    booking.customerName = lastName;
    booking.publicNotes = email;
    // booking.fiscalName = role;
    // user.username = username;
    // user.password = '1234';
    return booking;
});

I tried also with:
import define from "typeorm-seeding";

or:
import * as define from "typeorm-seeding;

with no luck, obviously!

Hence this issue, thank you!

Error: Cannot find module (typeorm entity)

When I do seed:run in my NestJS app I get the following error:

๏ฟฝ  TypeORM Seeding v1.6.1
- Loading ormconfig
โœ” ORM Config loaded
- Import Factories
โœ– Could not import factories!
Error: Cannot find module 'src/users/user.entity'
Require stack:
- C:\Users\User\Development\example\example-api\src\database\factories\user.factory.ts
- C:\Users\User\Development\example\example-api\node_modules\typeorm-seeding\dist\utils\file.util.js
- C:\Users\User\Development\example\example-api\node_modules\typeorm-seeding\dist\commands\seed.command.js
- C:\Users\User\Development\example\example-api\node_modules\typeorm-seeding\dist\cli.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:797:15)
    at Function.Module._load (internal/modules/cjs/loader.js:690:27)
    at Module.require (internal/modules/cjs/loader.js:852:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (C:\Users\User\Development\example\example-api\src\database\factories\user.factory.ts:3:1)
    at Module._compile (internal/modules/cjs/loader.js:959:30)
    at Module.m._compile (C:\Users\User\Development\example\example-api\node_modules\ts-node\src\index.ts:858:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:995:10)
    at Object.require.extensions.<computed> [as .ts] (C:\Users\User\Development\example\example-api\node_modules\ts-node\src\index.ts:861:12)
    at Module.load (internal/modules/cjs/loader.js:815:32) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\User\\Development\\example\\example-api\\src\\database\\factories\\user.factory.ts',
    'C:\\Users\\User\\Development\\example\\example-api\\node_modules\\typeorm-seeding\\dist\\utils\\file.util.js',
    'C:\\Users\\User\\Development\\example\\example-api\\node_modules\\typeorm-seeding\\dist\\commands\\seed.command.js',
    'C:\\Users\\User\\Development\\example\\example-api\\node_modules\\typeorm-seeding\\dist\\cli.js'
  ]
}

This is my seed:config:

๏ฟฝ  TypeORM Seeding v1.6.1
{
  type: 'postgres',
  host: 'localhost',
  port: 5432,
  username: 'example',
  password: 'example',
  database: 'example',
  entities: [ 'dist/**/*.entity{.ts,.js}' ],
  migrations: [ 'migration/*.js' ],
  cli: { migrationsDir: 'migration' },
  synchronize: true,
  factories: [ 'src/database/factories/**/*{.ts,.js}' ],
  seeds: [ 'src/database/seeds/**/*{.ts,.js}' ]
}

TypeORM is working fine with my app, but not this seeding package.

Error on seed:run

Hello all,

First of all thank you very much for the library is definitely a must! I've been trying to implement it in a project and I don't seem to be able to make it work.
Im implementing NestJS 7 with Typeorm and Postgres
Could you please help me out?

I keep on having this errors:

EntityMetadataNotFound: No metadata for <ENTITY_here> was found.

Error: Could not save entity
    at EntityFactory.<anonymous> (.........../node_modules/typeorm-seeding/src/entity-factory.ts:52:15)

Output of the seed:config without the database configurations

{
  type: 'postgres',
  url: undefined,
  sid: undefined,
  schema: undefined,
  extra: undefined,
  synchronize: false,
  dropSchema: false,
  migrationsRun: false,
  entities: [ 'src/**/*.entity{.ts', '.js}' ],
  migrations: [],
  migrationsTableName: undefined,
  subscribers: [],
  logging: [],
  logger: undefined,
  entityPrefix: undefined,
  maxQueryExecutionTime: undefined,
  debug: undefined,
  cli: {
    entitiesDir: undefined,
    migrationsDir: undefined,
    subscribersDir: undefined
  },
  cache: undefined,
  uuidExtension: undefined,
  factories: [ 'src/**/*.factory{.ts,.js}' ],
  seeds: [ 'src/**/*.seed{.ts,.js}' ]
}

Im trying with a simple entity, factory and seeder

export default class CreateCats implements Seeder {
  public async run(factory: Factory): Promise<void> {
    await factory(Cats)().createMany(5);
  }
}


define(Cats, (faker: typeof Faker) => {
  const cat = new Cats();
  cat.name = "CaT";
  cat.age = 22;

  return cat;
});


@Entity({
  name: "cats",
  orderBy: {
    createdAt: "ASC",
  },
})
export class Cats {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  age: number;
}


What am I missing?

Thank you in advance and I really hope I can use this library because it would save me loads of time

jsonb type in column throws error

Hi! I am unable to seed a jsonb type of field on a PostgreSQL 10.0 database. The error does not occur during insertion and update queries, only on seeding. This is my model:

import { IsNotEmpty } from 'class-validator';
import {
    Column, CreateDateColumn, Entity, ManyToOne, PrimaryColumn, UpdateDateColumn
} from 'typeorm';

import { Session } from './Session';

@Entity()
export class Resource {
    @PrimaryColumn('uuid')
    public id: string;

    @IsNotEmpty()
    @Column()
    public source: string;

    @IsNotEmpty()
    @Column({ type: 'jsonb'}) // Tried with `jsonb` by itself and same error.
    public data: any;

    @UpdateDateColumn({ name: 'updated_at' })
    public updatedAt: Date;

    @CreateDateColumn({ name: 'created_at' })
    public createdAt: Date;

    @ManyToOne(type => Session, session => session.resources)
    public session: Session;
}

And here is my factory:

import * as Faker from 'faker';
import { define } from 'typeorm-seeding';
import * as uuid from 'uuid';

import { Resource } from '../../../src/api/models/Resource';

define(Resource, (faker: typeof Faker) => {
    const source = faker.company.companyName();

    const resource = new Resource();
    resource.id = uuid.v1();
    resource.source = source;
    // resource.data = 12; // Works ok, but I need an object!
    // resource.data = "hello my github friends"; // Works ok, but I need an object!
    // resource.data = new Object({ foo: 'bar' }); // Does not work!
    resource.data = { foo: 'bar' }; // Does not work either!
    return resource;
});

Which throws a:

Could not run seed  Error: Could not save entity
    at EntityFactory.<anonymous> (/Users/humbertowoody/Proyectos/VR3/fetchbug-api/node_modules/typeorm-seeding/dist/typeorm-seeding.js:102:27)
    at Generator.throw (<anonymous>)
    at rejected (/Users/humbertowoody/Proyectos/VR3/fetchbug-api/node_modules/typeorm-seeding/dist/typeorm-seeding.js:30:65)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)

Is there a problem on seeding jsonb type of columns? Thanks in advance!

`context` is not inserted by default?

Hi, I'm trying to make some factories that make use of context.

Take a slightly modified version of the sample:

import * as Faker from 'faker'
import { define } from '../../src/typeorm-seeding'
import { User } from '../entities/User.entity'

// user.factory.ts

define(User, (faker: typeof Faker) => {
  const gender = faker.random.number(1)
  const firstName = faker.name.firstName(gender)
  const lastName = faker.name.lastName(gender)
  const email = faker.internet.email(firstName, lastName)

  const user = new User()
  user.firstName = firstName
  user.lastName = lastName
  user.middleName = null
  user.email = email
  user.password = faker.random.word()

  user.roles = ['basic']; /* <---- Explicitly declare default for roles */

  return user
});

// pet.factory.ts

define(Pet, (faker: typeof Faker) => {
  const gender = faker.random.number(1)
  const name = faker.name.firstName(gender)

  const pet = new Pet()
  pet.name = name
  pet.age = faker.random.number()

  pet.user = factory(User)({ roles: ['admin'] }) as any /* <---- Expect this to override ["basic"] */

  return pet
});

Expected behavior

  • Specified a "default" user.roles = ["basic"] in user.factory.ts
  • If create user with passed context (e.g. factory(User)({ roles: ['admin'] })) then the created user will have roles = ['admin']
  • Otherwise, default to the value specified in the module: roles = ['basic']

Actual behavior

  • In the above example,

Question/Suggestions

It looks like the correct way to do this would be:

define(User, (faker: typeof Faker, context: Record<string, any>) => {
  // ...
  user.roles = context.roles || ['basic']; /* <---- Explicitly declare default for roles */

  return user
});

Is that correct? (I've got mine working for this.) If so, it does kind of junk up the factory factory.

Would it perhaps be possible to add on the context after the fact as appears to be the case with a call like factory(User)().make({ roles: ['admin'] })

Alternatively, is there any downside associated with something like this?

// user.factory.ts

// LEAVE AS-IS

// pet.factory.ts

define(Pet, (faker: typeof Faker) => {
  // ....
  pet.user = factory(User)().make({ roles: ['admin'] }) as any /* <---- Expect this to override ["basic"] */

  return pet
});

This also seems to work. Looking here, returning a promise does seem to be kosher.

If so, would it make sense to change the signature of FactoryFunction to:

export type FactoryFunction<Entity, Context> = (faker: typeof Faker, context?: Context) => Entity | Promise<Entity>

so that you could make this fact a bit more explicit? For example:

define(Pet, async (faker: typeof Faker) => {
  // ....
  pet.user = await factory(User)().make({ roles: ['admin'] }) as any /* <---- Expect this to override ["basic"] */

  return pet
});

I guess the downside of this suggestion is that you want to help people to avoid calling create before the parent has been validated/created? Perhaps there are also potential circular dependency issues?

Use with .env

Hey

Currently it's static, using the ormconfig.js. But I use .env as config. Are there any chance to get this run with .env?

Thank you

Allow to override faker's attributes in the seed and make methods

With Laravel factories, you can do this:

$user = factory(App\User::class)->create([
    'type' => 'Admin',
]);

Which is great, because it allows to quickly create many entities with the specified attributes. Right now this is not possible in typeorm-seeding and you're forced into writing something like this:

const bruce = await factory(User)().make();
const em = connection.createEntityManager();

bruce.name = 'Bruce Lee';
await em.save<Entity>(bruce);

Or for many users:

const tenAdmins = await factory(User)().makeMany(10);
const em = connection.createEntityManager();
tenAdmins.forEach(user => user.type = 'Admin');
await Promise.all(tenAdmins.map(user => em.save<Entity>(user)));

Which feels awkward to do.

Using the map() method feels less awkward. For a single key you can get away inlining the function but for multiple keys overriding you'll need to make it too verbose or lose some type safety.

const tenAdmins = await factory(User)()
  .map((user) => {
     user.type = 'Admin';
     user.name = 'John Doe';
     return user;
  })
  .seedMany(10);

I'm proposing that we make the methods make and seed (and as the second argument for makeMany and seedMany) that accepts an object that overrides the faker attributes.

Improve error output

Errors that occur during seeding are catched. Then a new error is thrown which does not include the original error message/name.

EntityFactory:

try {
  const entity = yield this.make();
  return yield em.save(entity);
}
catch (error) {
  throw new Error('Could not save entity');
}

Add a changelog

I would love if we could include a changelog in the repo or release notes within GithHub (my preference is a CHANGELOG.md file). Not only will this help me keep track of library changes as new releases are made, but this will help out with automated tools like Dependabot when embedding changes in PRs it opens.

Typeorm should be a peerDependency

Hi guys, I'm running into an issue in my project where typeorm-seeding is installing its own typeorm library on top of the one I install for my project. This causes some issues, especially surrounding typing in Typescript projects when implementing Seeders.

Typeorm should be listed as a peer-dependency in this library to avoid duplicate Typeorm libs from being installed for end users (like me).

In my specific case this is the error I hit:

import { Factory, Seeder } from 'typeorm-seeding';
import { Connection } from 'typeorm';

export class CreateStreams implements Seeder {
  public async run(factory: Factory, connection: Connection) {
  }
}

TS error displayed:

Property 'run' in type 'CreateStreams' is not assignable to the same property in base type 'Seeder'.
  Type '(factory: import("/Volumes/work_projects/slewsystems_pi67_webserver/node_modules/typeorm-seeding/dist/types").Factory, connection: import("/Volumes/work_projects/slewsystems_pi67_webserver/node_modules/typeorm/connection/Connection").Connection) => Promise<...>' is not assignable to type '(factory: import("/Volumes/work_projects/slewsystems_pi67_webserver/node_modules/typeorm-seeding/dist/types").Factory, connection: import("/Volumes/work_projects/slewsystems_pi67_webserver/node_modules/typeorm-seeding/node_modules/typeorm/connection/Connection").Connection) => Promise<...>'.
    Types of parameters 'connection' and 'connection' are incompatible.
      Type 'import("/Volumes/work_projects/slewsystems_pi67_webserver/node_modules/typeorm-seeding/node_modules/typeorm/connection/Connection").Connection' is not assignable to type 'import("/Volumes/work_projects/slewsystems_pi67_webserver/node_modules/typeorm/connection/Connection").Connection'.
        Types of property 'options' are incompatible.
          Type 'import("/Volumes/work_projects/slewsystems_pi67_webserver/node_modules/typeorm-seeding/node_modules/typeorm/connection/ConnectionOptions").ConnectionOptions' is not assignable to type 'import("/Volumes/work_projects/slewsystems_pi67_webserver/node_modules/typeorm/connection/ConnectionOptions").ConnectionOptions'.

What you'll notice is the Connection type I define is located in:
node_modules/typeorm/connection/Connection
but the typoeorm-seeding types is looking in:
node_modules/typeorm-seeding/node_modules/typeorm/connection/Connection
because I have two typeorm libraries installed.

As a workaround I've been leveraging Yarn's resolution capabilities and its autodedup like this:

{
  "dependencies": {
    "typeorm": "^0.2.17",
  },
  "devDependencies": {
    "typeorm-seeding": "^1.0.0-rc.2"
  },
  "resolutions": {
    "typeorm-seeding/typeorm": "^0.2.17"
  }
}

where's the attach() API?

Hi w3tecch,

I can't see attach() API as written in the documentation.

await user.pets().attach(petIds)

May I ask for help? Because I can't create an entity later and attach it to the relationship.

Thanks,
Chen

EntityFactory using .map give me an error

I ran the example (User and Pet) that you have here and I am getting this error:

(property) User.pets: Pet[] This expression is not callable. Type 'Pet[]' has no call signatures.

I used this as seeder:

await factory(User)() .map(async (user: User) => { const pets: Pet[] = await factory(Pet)().createMany(2) const petIds = pets.map((pet: Pet) => pet.Id) await user.pets().attach(petIds) }) .createMany(5)

Any idea?

No repeat seeds in multi-run

More than a issue is a question,

There is a way to no repeat seeding? like migration that save the the last one executed and no repeated it.

Any plan to feature like this?

thank you!

Generation structure of seeding files

Hello!
Typeorm has command for generation migration files: typeorm migration:generate. Is planned the same feature in typeorm-seeding? This feature will by useful in cases when we want to fill database some data such as catalogues, lists etc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.