使用 TypeORM 找不到连接 "default"
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 创建连接它属性 "default" 如果我们不提供名称,情况就是这样对我来说。
我将 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);
。它会起作用
虽然Saras Arya提供了正确答案,但我也遇到了同样的错误
ConnectionNotFoundError: Connection "default" was not found.
由于我的 typeORM
实体确实有一个 @Entity()
装饰器并且它扩展了 BaseEntity
.
两人不能住在一起。
赞成的答案不一定正确,如果您不指定连接名称,它将默认为 "default"。
const manager = getConnectionManager().get('your_orm_name');
const repository = manager.getRepository<AModel>(Model);
对于那些正在寻找其他答案的人,请查看此内容。
就我而言,问题是因为我在数据库配置中传递了 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')
,这两种方法都有效。
如果有人在 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()
。
如果以后有人遇到这个问题,请检查一下以防万一:
我不小心做了“user.save()”而不是“userRepo.save(user)”。
(当然上面初始化连接是这样的:
const userRepo = getConnection(process.env.NODE_ENV).getRepository(用户))
我在将 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
名称更改为“默认”解决了这个问题。
我按照以下方法创建 Database
class。如果连接不存在,则它会创建连接,否则 return 现有连接。
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,请确保实体已专门导入并return编入数组。
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);
我知道这很奇怪,但有人可能需要这个:
Windows
相关原因。
我遇到了同样的错误,原因是当前位置设置的驱动器号为小写 (d:/apps/app-name/etc
)。
一旦我更新了目录更改指令以使用大写 D
(D:/apps/app-name/etc
).
,问题就得到了解决
我们正在使用 lerna
并使用程序包 B
中库 A
中的代码。
问题是每个包中的两个 TypeOrm 版本不同。
解决方案是确保每个包中安装的版本完全相同。
为了安全起见,请删除您的 node_modules
目录并使用 yarn install
或 npm install
重新安装所有内容
检查您的 yarn.lock
是否有多个条目 typeorm
并确保只有一个。
验证两个包中的 TypeOrm 版本相同后,即外部包和消费者存储库,如@InsOp 所述,问题仍然存在,那么问题可能是-
基本上当我们创建一个外部包时 - TypeORM 会尝试获取 "default" 连接选项,但如果找不到则抛出错误:
ConnectionNotFoundError: Connection "default" was not found.
我们可以通过在建立连接之前进行某种 完整性检查 来解决这个问题 - 幸运的是我们在 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();
}
以上是一个快速代码片段,它是此问题的实际根本原因,但如果您有兴趣查看完整的工作存储库(不同示例)-
- 外部 NPM 包:
- Git 回购:git-unit-of-work(特定文件 - src/providers/typeorm/typeorm-uow.ts)
- 在 NPM 中发布:npm-unit-of-work
- 以上包的消费者:nest-typeorm-postgre(特定文件- package.json、src/countries/countries.service.ts & countries.module.ts)
在我的例子中,我有一组多个连接,而不是只有一个。您有 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 与 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 创建连接它属性 "default" 如果我们不提供名称,情况就是这样对我来说。
我将 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);
。它会起作用
虽然Saras Arya提供了正确答案,但我也遇到了同样的错误
ConnectionNotFoundError: Connection "default" was not found.
由于我的 typeORM
实体确实有一个 @Entity()
装饰器并且它扩展了 BaseEntity
.
两人不能住在一起。
赞成的答案不一定正确,如果您不指定连接名称,它将默认为 "default"。
const manager = getConnectionManager().get('your_orm_name');
const repository = manager.getRepository<AModel>(Model);
对于那些正在寻找其他答案的人,请查看此内容。
就我而言,问题是因为我在数据库配置中传递了 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')
,这两种方法都有效。
如果有人在 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()
。
如果以后有人遇到这个问题,请检查一下以防万一:
我不小心做了“user.save()”而不是“userRepo.save(user)”。
(当然上面初始化连接是这样的:
const userRepo = getConnection(process.env.NODE_ENV).getRepository(用户))
我在将 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
名称更改为“默认”解决了这个问题。
我按照以下方法创建 Database
class。如果连接不存在,则它会创建连接,否则 return 现有连接。
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,请确保实体已专门导入并return编入数组。
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);
我知道这很奇怪,但有人可能需要这个:
Windows
相关原因。
我遇到了同样的错误,原因是当前位置设置的驱动器号为小写 (d:/apps/app-name/etc
)。
一旦我更新了目录更改指令以使用大写 D
(D:/apps/app-name/etc
).
我们正在使用 lerna
并使用程序包 B
中库 A
中的代码。
问题是每个包中的两个 TypeOrm 版本不同。
解决方案是确保每个包中安装的版本完全相同。
为了安全起见,请删除您的 node_modules
目录并使用 yarn install
或 npm install
检查您的 yarn.lock
是否有多个条目 typeorm
并确保只有一个。
验证两个包中的 TypeOrm 版本相同后,即外部包和消费者存储库,如@InsOp 所述,问题仍然存在,那么问题可能是-
基本上当我们创建一个外部包时 - TypeORM 会尝试获取 "default" 连接选项,但如果找不到则抛出错误:
ConnectionNotFoundError: Connection "default" was not found.
我们可以通过在建立连接之前进行某种 完整性检查 来解决这个问题 - 幸运的是我们在 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();
}
以上是一个快速代码片段,它是此问题的实际根本原因,但如果您有兴趣查看完整的工作存储库(不同示例)-
- 外部 NPM 包:
- Git 回购:git-unit-of-work(特定文件 - src/providers/typeorm/typeorm-uow.ts)
- 在 NPM 中发布:npm-unit-of-work
- 以上包的消费者:nest-typeorm-postgre(特定文件- package.json、src/countries/countries.service.ts & countries.module.ts)
在我的例子中,我有一组多个连接,而不是只有一个。您有 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...