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 数据库了!

相关推荐
火山引擎开发者社区4 小时前
火山引擎发布《企业级 ArkClaw 安全白皮书》
人工智能
爱勇宝4 小时前
第 1 章:别把“需求文档”当成真正的需求
前端·后端·程序员
阿里云大数据AI技术4 小时前
Hologres AI Function 文本分类实战:从提示词设计到 KV-Cache 调优,全程 SQL 搞定
人工智能·sql
白帽小丑5 小时前
# 一次 MySQL DELETE 误操作的数据恢复尝试实录
数据库·mysql
梨子同志5 小时前
常用命令
前端
code_pgf5 小时前
AI-Agent记忆机制分析
大数据·人工智能
梨子同志5 小时前
React 状态管理
前端
Dxy12393102166 小时前
MySQL索引完整教程:创建、查看、修改、删除与日常管理
前端·javascript·mysql