mysql typeorm“创建数据库”迁移

aiazj4mn  于 2023-01-20  发布在  Mysql
关注(0)|答案(3)|浏览(207)

我需要在连接之前创建数据库并使用db。我正在使用nest.js typeorm,提供了所有配置。当我启动我的应用程序时,它说"无法连接到数据库。错误:ER_BAD_DB_ERROR: Unknown database 'test'".
再一次:在我的MySQL Workbench中没有DB "Test" =〉当我启动应用程序时,我希望应用程序自己创建数据库(而不是由我手动创建)
有可能吗?

6ioyuze2

6ioyuze21#

我找到了一种方法来实现postgresql。我也使用Nest.js和Typeorm。首先,我创建了两个sql文件(一个用于检查数据库是否存在,一个用于创建数据库),然后创建了一个数据库配置文件。这些文件的内容如下所示。

  • checkDbIfExists.sql
  • SELECT 1 FROM pg_database WHERE datname = 'test'
  • createDB.sql
  • CREATE DATABASE test
  • config.ts
import { DynamicModule } from '@nestjs/common';
   
   import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
   import { createConnection, getManager } from 'typeorm';
   import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions';
   import * as path from 'path';
   
   const fs = require('fs');
   const checkDBScript: string = fs
     .readFileSync(path.join(__dirname, '../script/checkDBIfExists.sql'))
     .toString();
   const createDb: string = fs.readFileSync(path.join(__dirname, '../script/createDB.sql')).toString();
   
   const CreateDBIfNotExists = async (options: TypeOrmModuleOptions): Promise<void> => {
     const connection = await createConnection(options as PostgresConnectionOptions);
   
     const manager = getManager();
     const result = await manager.query(checkDBScript);
   
     if (result.length === 0) await manager.query(createDb);
   
     connection.close();
   };
   
   const DBConfig = async (): Promise<DynamicModule> => {
     let options: TypeOrmModuleOptions = {
       type: 'postgres',
       host: 'localhost',
       port: 5432,
       username: 'postgres',
       password: 'asd',
       entities: [],
       synchronize: true,
       cli: {
         migrationsDir: 'persistence/migrations'
       }
     };
   
     await CreateDBIfNotExists(options);
   
     options = { ...options, database: 'test' };
   
     return TypeOrmModule.forRoot(options);
   };
   
   export default DBConfig;

然后我加了这几行

  • nest-cli.json
"compilerOptions": {
     "assets": ["persistence/script/*"]
   }
  • app.module.ts
@Module({
   imports: [DBConfig()]
   ...
mbzjlibv

mbzjlibv2#

NestJS无法创建数据库,您需要在启动应用程序之前手动创建。
如果希望自动执行此操作,可以在使用docker-compose up启动Docker合成时使用Docker服务创建数据库

version: "3.6"

services:
  db:
    image: mysql:8.0.20
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - 3306:3306
    environment:
      - MYSQL_DATABASE=<database-name>
      - MYSQL_ROOT_PASSWORD=<password>
cx6n0qe3

cx6n0qe33#

我使用的是TypeORM版本0.3.11,因此虽然M. Erim Tuzcuoglu的解决方案目前可以工作,但它使用的是过时的方法。
下面是我的函数,它基于较新的DataSource方法。

export const createDBIfNotExists = async (): Promise<void> => {
  const dbOptions = dbConfig().db;
  const { createDatabase, database } = dbOptions;

  if (!createDatabase) {
    return;
  }

  const dataSource = new DataSource({
    type: 'postgres',
    ...dbOptions,
    database: 'postgres',
  });

  await dataSource.initialize();

  const result = await dataSource.query(
    `SELECT 1 FROM pg_database WHERE datname = '${database}'`
  );

  if (!result.length) {
    console.log(`Creating database with name "${database}"`);
    await dataSource.query(`CREATE DATABASE "${database}"`);
  }

  await dataSource.destroy();
}

指定postgres作为连接的数据库有点“笨拙”,因为它假设数据库存在,但是在我的例子中,这是可以接受的,没有它,连接将失败。
我还应该提到dbConfig函数与Nest文档中提供的方法非常相似:

// Use process.env for the values, I've hardcoded them just for clarity here
export const dbConfig = (): { db: IDBConfig } => ({
  db: {
    host: 'localhost',
    port: 5432,
    database: 'your-db-name',
    username: 'username',
    password: 'password',
    migrationsRun: true,
    createDatabase: true,
    logging: true,
    synchronize: false,
  },
});

然后在main.ts中调用函数:

async function bootstrap() {
  await createDBIfNotExists();
  // ...
}

这允许我简单地更改POSTGRES_DB env变量,它将在我启动应用程序时自动创建和使用此DB(同时还检查RUN_MIGRATION env)。
它是针对我的需求而设计的,但是我希望这个通用的实现示例能够在将来对某些人有所帮助。

相关问题