[英]Connection "default" was not found with TypeORM
我将 TypeORM 与 NestJS 一起使用,但无法正确保存实体。
连接创建工作,postgres 在 5432 端口上运行。 凭证也可以。
但是,当我需要使用 entity.save() 保存资源时,我得到了:
Connection "default" was not found.
Error
at new ConnectionNotFoundError (/.../ConnectionNotFoundError.ts:11:22)
我检查了 TypeORM ConnectionManager 的源文件( https://github.com/typeorm/typeorm/blob/master/src/connection/ConnectionManager.ts )但似乎 TypeORM 第一次创建连接时它属性“默认”名称如果我们不提供,对我来说就是这种情况。
我将 TypeORM 与 TypeOrmModule 设置为
TypeOrmModule.forRoot({
type: config.db.type,
host: config.db.host,
port: config.db.port,
username: config.db.user,
password: config.db.password,
database: config.db.database,
entities: [
__dirname + '/../../dtos/entities/*.entity.js',
]
})
当然,我的常数是正确的。 有任何想法吗?
您正在尝试在未建立连接的情况下创建存储库或管理器。
尝试这样做const shopkeeperRepository = getRepository(Shopkeeper);
在一个函数里面。 它会起作用的
赞成的答案不一定正确,如果您不指定连接名称,它将默认为“默认”。
const manager = getConnectionManager().get('your_orm_name');
const repository = manager.getRepository<AModel>(Model);
如果以后有其他人遇到这个问题,请检查一下以防万一:
我不小心做了“ user.save()
”而不是“ userRepo.save(user)
”。
(当然上面初始化连接是这样的:
const userRepo = getConnection(process.env.NODE_ENV).getRepository(User)
我们正在使用lerna
并使用包B
中库A
中的代码。
问题是每个包中的两个 TypeOrm 版本都不同。
解决方案是确保您在每个软件包中安装了完全相同的版本。
为了安全起见,请删除您的node_modules
目录并使用yarn install
或npm install
重新安装所有内容
检查您的yarn.lock
是否有多个typeorm
条目,并确保只有一个。
如果有人使用带有getRepository()
的 Express Router,请检查下面的代码
const router = Router();
router.get("/", async function (req: Request, res: Response) {
// here we will have logic to return all users
const userRepository = getRepository(User);
const users = await userRepository.find();
res.json(users);
});
router.get("/:id", async function (req: Request, res: Response) {
// here we will have logic to return user by id
const userRepository = getRepository(User);
const results = await userRepository.findOne(req.params.id);
return res.send(results);
});
只需确保像 Saras Arya 在接受的答案中所说的那样在每条路线中调用getRepository()
即可。
我按照以下方法创建Database
类。 如果连接不存在,则创建连接,否则返回现有连接。
import { Connection, ConnectionManager, ConnectionOptions, createConnection, getConnectionManager } from 'typeorm';
export class Database {
private connectionManager: ConnectionManager;
constructor() {
this.connectionManager = getConnectionManager();
}
public async getConnection(name: string): Promise<Connection> {
const CONNECTION_NAME: string = name;
let connection: Connection;
const hasConnection = this.connectionManager.has(CONNECTION_NAME);
if (hasConnection) {
connection = this.connectionManager.get(CONNECTION_NAME);
if (!connection.isConnected) {
connection = await connection.connect();
}
} else {
const connectionOptions: ConnectionOptions = {
name: 'default',
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'password',
database: 'DemoDb',
synchronize: false,
logging: true,
entities: ['src/entities/**/*.js'],
migrations: ['src/migration/**/*.js'],
subscribers: ['src/subscriber/**/*.js'],
};
connection = await createConnection(connectionOptions);
}
return connection;
}
}
如果您使用的是 webpack,请确保实体是专门导入并以数组形式返回的。
import {User} from 'src/entities/User.ts';
import {Album} from 'src/entities/Album.ts';
import {Photos} from 'src/entities/Photos.ts';
const connectionOptions: ConnectionOptions = {
name: 'default',
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'password',
database: 'DemoDb',
synchronize: false,
logging: true,
entities: [User, Album, Photos],
migrations: ['src/migration/**/*.js'],
subscribers: ['src/subscriber/**/*.js'],
};
最后
const connectionName = 'default';
const database = new Database();
const dbConn: Connection = await database.getConnection(connectionName);
const MspRepository = dbConn.getRepository(Msp);
await MspRepository.delete(mspId);
对于那些正在寻找其他答案的人,请查看此内容。
就我而言,问题是因为我在我的数据库配置中传递了name
。
export const dbConfig = {
name: 'myDB',
...
}
await createConnection(dbConfig) // like this
结果,唯一的连接服务器知道myDB
不是default
。
同时,在我的服务中,没有name
的存储库被注入,这将回退到default
。 (服务将因此寻找default
连接)
@Service() // typedi
export class Service {
constructor(
// inject without name -> fallback to default
@InjectRepository() private readonly repository
) {}
}
作为修复,我删除了我的数据库配置中的name
属性。
或者您可以将myDB
作为InjectRepository
的参数传递,例如@InjectRepository('myDB')
,无论哪种方式都有效。
在不同环境中使用getConnectionOptions
时出现此错误。 使用一个数据库进行开发,另一个用于测试。 这就是我修复它的方法:
const connectionOptions = await getConnectionOptions(process.env.NODE_ENV);
await createConnection({...connectionOptions, name:"default"});
我使用getConnectionOptions
来获取当前环境的连接,为了成功地做到这一点,您必须将ormconfig.json
更改为一个数组,其中包含您想要的不同环境的键“name”,如下所示:
[
{
"name" : "development",
"type": "USER",
"host": "localhost",
"port": 5432,
"username": "postgres",
"password": "PASS",
"database": "YOURDB"
},
{
"name" : "test",
"type": "USERTEST",
"host": "localhost",
"port": 5432,
"username": "postgres",
"password": "PASSTEST",
"database": "YOURDBTEST"
}
]
现在connectionOptions
将包含当前环境的连接参数,但是将其加载到createConnection
会引发您指出的错误。 将connectionOptions
名称更改为“默认”解决了该问题。
我知道这很奇怪,但有人可能需要这个:
Windows
相关的原因。
我遇到了由小写驱动器号( d:/apps/app-name/etc
)设置的当前位置引起的相同错误。
一旦我更新目录更改指令以使用大写D
( D:/apps/app-name/etc
),问题就得到了解决。
在验证两个包中的 TypeOrm 版本相同后,即@InsOp 提到的外部包和消费者存储库仍然存在问题,那么问题可能是 -
基本上,当我们创建一个外部包时——TypeORM 会尝试获取“默认”连接选项,但如果未找到,则会引发错误:
ConnectionNotFoundError:未找到连接“默认”。
我们可以通过在建立连接之前进行某种健全性检查来解决这个问题——幸运的是,我们在getConnectionManager()
上有.has()
方法。
import { Connection, getConnectionManager, getConnectionOptions,
createConnection, getConnection, QueryRunner } from 'typeorm';
async init() {
let connection: Connection;
let queryRunner: QueryRunner;
if (!getConnectionManager().has('default')) {
const connectionOptions = await getConnectionOptions();
connection = await createConnection(connectionOptions);
} else {
connection = getConnection();
}
queryRunner = connection.createQueryRunner();
}
上面是一个快速代码片段,它是此问题的实际根本原因,但如果您有兴趣查看完整的工作存储库(不同示例) -
就我而言,我有一组多个连接,而不仅仅是一个。 你有 2 个选择。
default
命名连接,例如:createConnections([
{
name: 'default',
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'users',
entities: [`${__dirname}/entity/*{.js,.ts}`],
synchronize: true,
logging: true
}
]);
import {getConnection} from "typeorm";
const db1Connection = getConnection("db1Connection");
// you can work with "db1" database now...
对于那些仍在寻找答案的人,我找到了一个对我有帮助的人。 我正在将 TypeORM 与 Express 一起使用,似乎 Express 先执行连接而不是 typeorm。 marc_s 在这个链接上给出了这个答案
在我自己的情况下,实际问题是我的index
文件导入了我的router
文件,该文件导入了我的控制器,然后导入了我的服务(调用getRepository
的地方)。 因此,在建立连接之前,导入正在解析(以及对getRepository
的调用)。
我考虑实施Sarya 的答案,但它会让我的代码更加冗长。
我所做的是创建一个函数来连接到db/index.ts
文件中的数据库
import { createConnection } from "typeorm";
export const getDBConnection = async () => {
const dbConnection = await createConnection();
if (!dbConnection.isConnected) await dbConnection.connect();
return dbConnection;
}
然后创建一个异步函数来引导我的应用程序。 在实例化我的应用程序之前,我等待getDBConnection
解决,然后我导入我的路由器文件。 这样,导入解析仅在建立连接后发生。
routers/index.ts
import { Router } from 'express';
const router = Router();
/* ... route configurations ... */
export default router;
app.ts
const bootstrap = async () => {
try {
// wait on connection to be established
await getDBConnection();
} catch (error) {
// log error then throw
throw error;
}
// create app
const app = express();
// some middleware configuration...
// now import and setup the router
const { default: router } = await import("./routers");
app.use("/api", router);
// some more middleware configuration...
const server = http.createServer(app);
server.listen(3000, () => console.log('app running at port: 3000'));
};
bootstrap();
我对以下代码有同样的问题:
import { HttpException, Inject, NotFoundException } from "@nestjs/common";
import { Not } from "typeorm";
import { Transactional } from "typeorm-transactional-cls-hooked";
import { TENANT_CONNECTION } from "../tenant/tenant.module";
import {Feriados} from './feriados.entity';
export class FeriadosService {
repository: any;
constructor(
@Inject(TENANT_CONNECTION) private connection)
{
this.repository = connection.getRepository(Feriados)
}
@Transactional()
async agregar(tablaNueva: Feriados): Promise<Number> {
const tablaAGuardar = await this.repository.create(tablaNueva)
return await this.guardar(tablaAGuardar)
}
@Transactional()
async actualizar(tablaActualizada: Feriados): Promise<Number>{
const tablaAGuardar = await this.repository.merge(tablaActualizada);
return await this.guardar(tablaAGuardar)
}
async guardar(tabla:Feriados){
await this.repository.save(tabla)
return tabla.id
}
我通过删除 2 @Transactional() 来修复它,希望有人帮助。
在typeorm v0.3
中, Connection
API 被DataSource
API 替换。 NestJS 也适应了这一变化,因此如果您依赖旧的 API(例如getConnection
方法),您可能会看到Connection "default" was not found
错误。
您可以在发行说明中阅读有关更改和新 API 的信息: https://github.com/typeorm/typeorm/releases/tag/0.3.0
如果您使用getConnection
,则可以改用app.get(DataSource)
。
在新版本的 Typeorm 0.3.7 中,下一个解决这个问题的方法是:
在 app.module.ts 中,更改 AppModule class 的构造函数并创建一个返回 Datasource 的方法:
export class AppModule { constructor(private dataSource: DataSource) {} getDataSource() { return this.dataSource; } }
然后,在您需要使用的文件中添加:
const repository = app.get(AppModule).getDataSource().getRepository('Entity_name');
虽然 Saras Arya 提供了正确的答案,但我遇到了同样的错误
ConnectionNotFoundError:未找到连接“默认”。
由于我的typeORM
实体确实有一个@Entity()
装饰器以及它扩展了BaseEntity
。
两个人不能住在一起。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.