2.4. PostgreSQL 数据库连接与实战指南

🚀 关于 ai-data-analyzer

本文档属于开源项目 ai-data-analyzer 的技术文档系列。这是一个专为 AI 数据分析场景打造的全栈解决方案,包含前端可视化、Nest.js 后端服务、数据库设计、AI Agent 集成等完整模块。欢迎 Star、Fork 和贡献代码!

本文档将手把手教你如何在 Nest.js 项目中安装、配置、连接并使用 PostgreSQL 数据库。我们将使用 Docker 来快速启动数据库,并使用 TypeORM 来进行数据操作。

1. 准备工作

在开始之前,请确保你的电脑上已经安装了以下工具:

  • Docker Desktop: 用于运行数据库容器。
  • Node.jspnpm: 用于运行后端项目。

2. 安装与启动数据库 (使用 Docker)

我们不需要在电脑上直接安装 PostgreSQL 软件,而是使用 Docker 容器,这样更干净、方便管理。

2.1 配置 docker-compose.yml

项目根目录 (ai-data-analyzer) 下,确保有一个 docker-compose.yml 文件。

注意 :不是在 backend 目录下,而是在最外层的项目根目录下。这是为了方便统一管理整个项目的服务(将来可能还有前端、Redis 等)。

目录结构如下:

复制代码
ai-data-analyzer/
├── docker-compose.yml  <-- 放在这里
├── backend/
│   ├── .env
│   ├── src/
│   └── ...
└── frontend/

如果还没有该文件,请创建它:

yaml 复制代码
version: '3.8'
services:
  db:
    image: postgres:15-alpine
    container_name: ai_analyzer_postgres
    restart: always
    environment:
      POSTGRES_USER: your_username      # 数据库用户名
      POSTGRES_PASSWORD: your_password  # 数据库密码
      POSTGRES_DB: ai_analysis_db       # 数据库名称
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

2.2 启动数据库

在终端中,进入项目根目录,运行以下命令启动数据库:

bash 复制代码
docker-compose up -d
  • up: 启动容器。
  • -d: 后台运行 (detached mode)。

你可以使用 docker ps 命令检查数据库是否正在运行。如果看到 ai_analyzer_postgres 容器的状态是 Up,说明启动成功。

3. 配置 Nest.js 连接

现在数据库已经在运行了,我们需要配置 Nest.js 后端来连接它。

3.1 安装依赖

backend 目录下,安装 TypeORM 和 PostgreSQL 驱动:

bash 复制代码
cd backend
pnpm add @nestjs/typeorm typeorm pg

3.2 配置环境变量 (.env)

backend 目录下创建或编辑 .env 文件,填入与 docker-compose.yml 中一致的数据库信息:

env 复制代码
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USER=your_username
DATABASE_PASSWORD=your_password
DATABASE_NAME=ai_analysis_db

注意DATABASE_USERDATABASE_PASSWORDDATABASE_NAME 必须与 docker-compose.yml 中的 POSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_DB 完全一致,否则无法连接。

3.3 在 AppModule 中配置连接

打开 backend/src/app.module.ts,引入 TypeOrmModule 并配置连接:

typescript 复制代码
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
  imports: [
    // 1. 加载环境变量
    ConfigModule.forRoot({
      isGlobal: true, // 让配置在全局可用
    }),
    // 2. 配置数据库连接
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get<string>('DATABASE_HOST'),
        port: configService.get<number>('DATABASE_PORT'),
        username: configService.get<string>('DATABASE_USER'),
        password: configService.get<string>('DATABASE_PASSWORD'),
        database: configService.get<string>('DATABASE_NAME'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'], // 自动加载所有实体
        synchronize: false, // 生产环境建议关闭,使用迁移来管理数据库结构
      }),
    }),
    // ... 其他模块
  ],
})
export class AppModule {}

4. 验证连接

配置完成后,启动后端项目来验证连接是否成功:

bash 复制代码
# 在 backend 目录下
pnpm start:dev

观察终端输出。如果看到类似 [TypeOrmModule] Dependencies initialized 的日志,且没有报错,说明连接成功!

如果出现 password authentication failedConnection refused 错误,请检查:

  1. Docker 容器是否正在运行 (docker ps)。
  2. .env 中的用户名密码是否与 docker-compose.yml 一致。
  3. 是否重启过 Docker 容器以应用最新的配置 (docker-compose down -v 然后 docker-compose up -d)。

5. 如何在代码中使用数据库 (CRUD 实战)

连接成功后,我们就可以在服务中操作数据库了。这里以"保存分析结果"为例。

5.1 定义实体 (Entity)

实体是数据库表的映射。在 src/analysis-results/entities/analysis-result.entity.ts 中:

typescript 复制代码
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn } from 'typeorm';

@Entity('analysis_results') // 表名
export class AnalysisResult {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  title: string;

  @Column('text')
  content: string;

  @CreateDateColumn()
  createdAt: Date;
}

5.2 注册实体

在模块文件 (例如 src/analysis-results/analysis-results.module.ts) 中注册实体:

typescript 复制代码
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AnalysisResult } from './entities/analysis-result.entity';
import { AnalysisResultsService } from './analysis-results.service';
import { AnalysisResultsController } from './analysis-results.controller';

@Module({
  imports: [TypeOrmModule.forFeature([AnalysisResult])], // 注册实体
  controllers: [AnalysisResultsController],
  providers: [AnalysisResultsService],
})
export class AnalysisResultsModule {}

5.3 在服务中注入并使用 Repository

在 Service 中,我们通过构造函数注入 Repository,然后使用它来增删改查:

typescript 复制代码
// src/analysis-results/analysis-results.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AnalysisResult } from './entities/analysis-result.entity';

@Injectable()
export class AnalysisResultsService {
  constructor(
    @InjectRepository(AnalysisResult)
    private analysisResultRepository: Repository<AnalysisResult>,
  ) {}

  // 1. 创建并保存数据
  async create(title: string, content: string) {
    const newResult = this.analysisResultRepository.create({
      title,
      content,
    });
    return await this.analysisResultRepository.save(newResult);
  }

  // 2. 查询所有数据
  async findAll() {
    return await this.analysisResultRepository.find();
  }

  // 3. 根据 ID 查询
  async findOne(id: string) {
    return await this.analysisResultRepository.findOneBy({ id });
  }
}

现在,你已经学会了如何安装、配置、连接并使用 PostgreSQL 数据库了!

相关推荐
爱吃羊的老虎1 小时前
【数据库】模块二:SQL 语句、高级特性与优化
数据库·oracle
console.log('npc')1 小时前
Codex 桌面端接入 Headroom 压缩代理完整教程
前端·vscode
Sam09271 小时前
1 个 Java 服务可以支撑多少 SSE 连接:从线程模型到容量评估
java·人工智能·ai
极光代码工作室1 小时前
基于机器学习的新闻分类系统
人工智能·python·深度学习·机器学习
云飞云共享云桌面1 小时前
集中算力・统一数据・高效协同:SolidWorks 云桌面方案详解
运维·服务器·人工智能·安全·3d·电脑·制造
爱喝水的鱼丶1 小时前
SAP-ABAP:SAP表与视图权限管控方案:表维护权限、视图访问权限配置实操
运维·数据库·性能优化·sap·abap·权限·表和视图
tomcoding1 小时前
深入解析Oracle数据块的内部结构
数据库·oracle
陈天伟教授1 小时前
图解人工智能(59)人工智能应用-AI游戏
人工智能·游戏