解决 TypeORM 0.3+ 连接数据库的各种报错

2023年 7月 14日 61.1k 0

前言:TypeORM 0.3以上版本弃用了getConnectionManagercreateConnection等一系列api,使用 DataSource 代替原本的 Connection
详情查看 CHANGELOG.md

1. 解决代码更新时的报错

文件: pages/index.tsx,实现数据库连接

import {GetServerSideProps, NextPage} from "next";
import {AppDataSource} from "@/src/data-source"
import {User} from "@/src/entity/User";

type Props = {
  name: string
}

const Posts: NextPage = (props) => {
  return (
     你好 {props.name} 
  );
}
export default Posts;

export const getServerSideProps: GetServerSideProps = async (context) => {
  // createConnection 被弃用,使用 initialize 创建连接
  const connection = await dataSource.initialize()
  return {
    props: { name: 'Bumble' }
  };
};

以上代码可以成功连接数据库,但是在开发环境中,代码更新时会出现以下报错

Cannot create a "default" connection because connection to the database already established.

错误信息提示您正在尝试创建一个名为"default"的连接,但因为已经建立了与数据库的连接,所以无法创建新连接。
因此需要加判断,判断是否已有连接,复用连接。

解决方法:在代码中增加判断

export const getServerSideProps: GetServerSideProps = async (context) => {
  const UserRepository = AppDataSource.isInitialized
    ? AppDataSource.getRepository(User)
    : (await AppDataSource.initialize()).getRepository(User);
  return {
    props: { name: 'Bumble' }
  };
};

上述代码使用 isInitialized 判断是否已有连接,已有连接就使用getRepository获取 User 实体的存储库,无连接则先建立连接再获取实体存储库。

2. 解决报错 no metadata for User

上述代码实现了数据库连接,接下来实现数据查询。
查询 User 表的数据,代码实现:

export const getServerSideProps: GetServerSideProps = async (context) => {
  const UserRepository = AppDataSource.isInitialized
    ? AppDataSource.getRepository(User)
    : (await AppDataSource.initialize()).getRepository(User);
  // 使用 find() 就可以实现查询,但是此时会报错
  const users = await UserRepository.find()
  console.log(users)
  return {
    props: { name: 'Bumble' }
  };
};

报错内容

error - EntityMetadataNotFoundError: No metadata for "User" was found.

错误原因 TypeORM 无法找到与 “User” 实体相关的元数据。

解决方法:添加与 “User” 实体相关的元数据

export const getServerSideProps: GetServerSideProps = async (context) => {
  // @ts-ignore
  const dataSource = new DataSource({
    ...AppDataSource.options,
    entities: [User],
  });
  const UserRepository = dataSource.isInitialized
    ? dataSource.getRepository(User)
    : (await dataSource.initialize()).getRepository(User);
  const users = await UserRepository.find()
  console.log(users) // 成功打印出 User 表的所有数据
  return {
    props: { name: 'Bumble' }
  };
};

以上代码就可以成功打印出User表的所有数据了

3. 总结:完整代码优化

有多个实体时,代码会出现冗余,可以封装方法以优化代码。
以下是优化后的完整代码

import {GetServerSideProps, NextPage} from "next";
import {AppDataSource} from "@/src/data-source"
import {User} from "@/src/entity/User";
import {Post} from "@/src/entity/Post";
import {Comment} from "@/src/entity/Comment";
import {DataSource} from "typeorm";

type Props = {
  name: string
}

const Posts: NextPage = (props) => {
  return (
     你好 {props.name} 
  );
}
export default Posts;

export const getServerSideProps: GetServerSideProps = async (context) => {
  const UserRepository = await handleGetRepository(User)
  const PostRepository = await handleGetRepository(Post)
  const users = await UserRepository.find()
  const posts = await PostRepository.find()
  console.log(users, posts)
  return {
    props: {
      name: 'Bumble'
    }
  };
};

const handleGetRepository = async (entity) => {
  // @ts-ignore
  const dataSource = new DataSource({
    ...AppDataSource.options,
    entities: [User, Post, Comment],
  });
  return dataSource.isInitialized
    ? dataSource.getRepository(entity)
    : (await dataSource.initialize()).getRepository(entity);
}

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论