繁体   English   中英

“ConnectionNotFoundError:未找到连接“默认””- class 属性

[英]"ConnectionNotFoundError: Connection "default" was not found" - class attribute

我正在学习 NodeJS,任务是构建一个简单的消息服务。 老师用的是SQLite3,但是我决定用Postgres,因为这是我们公司项目用的DB。

错误:“ConnectionNotFoundError:未找到连接“默认””

// server.ts

import 'reflect-metadata';
import express from 'express';
import { createConnection } from 'typeorm';

import router from './router';

(async () => {
  const PORT = 3333;

  console.log('before');
  await createConnection();
  console.log('after');

  const app = express();

  app.use(express.json());
  app.use(express.urlencoded({ extended: true }));

  app.use(router);

  app.listen(PORT, () => {
    console.log(`App is running on port ${PORT}`);
  });
})();

我有以下MessagesService

// this works just fine
class MessagesService {
  async create({ user_id, text, admin_id }: MessagesCreateInterface): Promise<Message> {
    const repository = getCustomRepository(MessagesRepository);

    const message = repository.create({
      admin_id,
      text,
      user_id,
    });

    await repository.save(message);

    return message;
  }


  async listByUser(user_id: string): Promise<Array<Message>> {
    const repository = getCustomRepository(MessagesRepository);
    const messages = await repository.find({ user_id });
    return messages;
  }
}

由于在两个函数中都调用了getCustomRepository ,并尝试将其转换为 class 属性:

class MessagesService {
  repository: MessagesRepository;

  constructor() {
    console.log('constructor');
    this.repository = getCustomRepository(MessagesRepository);
  }
  ...
}

但后来我得到ConnectionNotFoundError: Connection "default" was not found. .

实验

  1. constructor中使用setTimeout :访问连接。

  2. Consoles.log:我打印了“之前”和“构造函数”,但没有打印“之后”。

有人可以帮助我了解发生了什么吗? 由于我正在使用异步/等待,因此在建立连接之前不应调用MessageService 我在这里打破了一些模式吗?

您没有将连接选项传递给 TypeORM,因此它不知道如何连接和设置连接(这是默认设置)。

不带参数调用await createConnection()将从文件加载连接选项,并且(据我所知)您没有任何ormconfig.X文件。

要将连接选项传递给 TypeORM,您有三个选项:

  1. 连接选项对象
    请参阅https://typeorm.io/#/connection
    调用createConnection({ ... })时直接传递连接选项(对象
    例子:
const connection = await createConnection({
    type: "postgres",
    host: "localhost",
    port: 5432,
    username: "test",
    password: "test",
    database: "test"
});
  1. ormconfig.X 文件
    请参阅https://typeorm.io/#/using-ormconfig
    在项目根目录中加载一个ormconfig.[extension]文件。
    支持的 ormconfig 文件扩展名是:.json、.js、.ts、.env、.yml 和 .xml。
    示例(ormconfig.json):
{
   "type": "postgres",
   "host": "localhost",
   "port": 5432,
   "username": "test",
   "password": "test",
   "database": "test"
}
  1. 环境变量
    请参阅https://typeorm.io/#/using-ormconfig/using-environment-variables
    TypeORM 会自动在环境变量中或在项目根目录(package.json 附近)的.envormconfig.env中搜索连接选项。
    例子:
TYPEORM_CONNECTION = postgres
TYPEORM_HOST = localhost
TYPEORM_PORT = 5432
TYPEORM_USERNAME = test
TYPEORM_PASSWORD = test
TYPEORM_DATABASE = test

问题是在server.ts上调用createConnection之前正在导入router.js

由于控制器在router.js内实例化,与服务和存储库一起,它们确实在创建之前尝试访问数据库连接。

我找到的解决方案是在建立连接后懒惰地导入router.js ,但我不确定这是否是一种反模式。

// server.ts

import 'reflect-metadata';
import express from 'express';
import { createConnection } from 'typeorm';

(async () => {
  await createConnection();
  // Importing routes after connection has been established
  const router = (await import('./router').default);
  const PORT = 3333;

  const app = express();

  app.use(express.json());
  app.use(express.urlencoded({ extended: true }));

  app.use(router);

  app.listen(PORT, () => {
    console.log(`App is running on port ${PORT}`);
  });
})();

讲座中建议的方法是在每条路线内创建一个控制器实例,但这对我来说似乎不正确。

router.js

// suggested way
router.post('/messages', (request, response) => {
  const messagesController = new MessagesController();
  return messagesController.create(request, response); 
});

router.get('/messages/:id', (request, response) => {
  const messagesController = new MessagesController();
  return messagesController.showByUser(request, response); 
});

由于我仍在学习 NodeJS,请随时纠正我并指出正确的方法。

我知道这个问题已被标记为已回答,但我最近遇到了类似的问题(与 mocha 的单元测试有关)。 就我而言,解决方案是存根 typeorm getCustomRepository

import sinon from 'sinon';
import * as typeorm from 'typeorm';
import {Connection, ConnectionManager} from 'typeorm';

describe('groupService', () => {

    let getCustomRepositoryStub;

    beforeEach(() => {
        getCustomRepositoryStub = sinon.stub(typeorm, 'getCustomRepository');
        sinon.stub(ConnectionManager.prototype, 'get').returns({getCustomRepository: getCustomRepositoryStub} as  Connection);
    });

    afterEach(() => {
        sinon.restore();
    });

    it('findById returns empty result', async() => {
        const groupId: string = 'mock-group-id';
        getCustomRepositoryStub.withArgs(GroupRepository)
            .returns({
                findById: () => Promise.resolve([])
            });
        const groups = await groupService.getGroup(groupId);
        expect(groups.length).equal(0);
    });

    ...

});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM