Go-Zero整合Goose实现MySQL数据库版本管理


推荐阅读
【系列好文】go-zero从入门到精通(看了就会)
教程地址:https://blog.csdn.net/u011019141/article/details/139619172


Go-Zero整合Goose实现MySQL数据库版本管理的教程

在开发中,数据库迁移和版本管理是必不可少的工作。为了确保数据库架构与代码的同步,需要采用一定的技术手段,确保在每次代码升级时,自动增量修改变动的SQL脚本。

goose 是一个非常受欢迎的数据库迁移工具,可以帮助我们管理 MySQL 数据库的版本。

本文将详细介绍如何将 goosego-zero 框架整合,实现 MySQL 数据库版本管理。

1. 介绍Goose和Go-Zero

  • Goose:Goose 是一个用于数据库迁移的工具,它支持多种数据库,并且可以通过SQL文件来定义数据库的变更。Goose的优势在于它简单易用,能够管理数据库的迁移、版本控制和回滚操作。

    Goose Github仓库地址:https://github.com/pressly/goose

    参考实现:https://pressly.github.io/goose/blog/2021/embed-sql-migrations/#but-why

  • Go-Zero:Go-Zero 是一个高效的 Go 微服务框架,提供了许多用于构建微服务的工具,比如代码生成、RPC框架、消息队列等。Go-Zero 也集成了数据库访问层,通过 sqlx 包操作 MySQL、PostgreSQL 等数据库。

本文将结合这两个工具,通过Go-Zero的数据库管理,使用Goose进行MySQL数据库的版本控制与迁移。

2. 项目结构

假设你已经有一个Go-Zero项目,下面是项目的结构:

your-project/
|-- migrations/             # 数据库迁移文件存放目录
|-- main.go                 # 程序入口
|-- go.mod                  # Go模块管理文件
|-- go.sum                  # Go模块依赖文件

3. 安装Goose

首先,你需要安装 goose 工具:

go get -u github.com/pressly/goose

安装成功后,可以通过命令行使用 goose 来管理数据库迁移。

4. 创建数据库迁移文件

数据库迁移文件用于定义 MySQL 数据库表和字段的更新操作。

migrations 目录下生成一个类似 00001_add_table.sql 的文件。

5. 编写迁移SQL

打开生成的 SQL 文件,定义数据库的表和字段。例如:

-- +goose Up
CREATE TABLE demo1 (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL,age INT NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO demo1 (name, age) VALUES ('Alice', 30);
CREATE TABLE demo2 (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL,age INT NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE demo3 (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL,age INT NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE demo4 (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL,age INT NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  • -- +goose Up:表示执行数据库迁移时的 SQL 语句。
  • -- +goose Down:表示回滚迁移时执行的 SQL 语句。

确保 SQL 文件没有多余的空格、换行或不可见字符,特别是文件编码格式应为 UTF-8。

来自Github仓库的说明:
每个迁移文件必须只有一个-- +goose Up注释。-- +goose Down注释是可选的。如果文件同时具有两个注释,则–
+goose Up注释必须先出现。

注意注释中的注解。后面的任何语句都-- +goose Up将作为前向迁移的一部分执行,后面的任何语句都-- +goose
Down将作为回滚的一部分执行。

默认情况下,所有迁移都在事务中运行。但是,某些语句(CREATE DATABASE如)无法在事务中运行。您可以选择将其添加-- +goose
NO TRANSACTION到迁移文件的顶部,以跳过该特定迁移文件中的事务。此文件中的 Up 和 Down 迁移都将在无事务的情况下运行。

默认情况下,SQL 语句以分号分隔 - 事实上,查询语句必须以分号结尾才能被 goose 正确识别。

6. 在Go-Zero中使用Goose

为了在 Go-Zero 中执行数据库迁移,我们需要将 goose 集成到 Go-Zero 的数据库管理流程中。

1. 配置数据库连接

在 Go-Zero 中,我们通过 sqlx 来操作 MySQL 数据库,因此首先需要配置好数据库连接。

package mainimport ("database/sql""log""github.com/pressly/goose"_ "github.com/go-sql-driver/mysql" // MySQL 驱动"github.com/zeromicro/go-zero/core/stores/sqlx"
)func migrateDatabase() {// 配置 MySQL 连接dsn := "root:123456@tcp(192.168.2.204:3306)/test?charset=utf8mb4"log.SetFlags(log.LstdFlags | log.Lshortfile) // 更详细的日志格式,包括时间戳和文件行号// 打开 MySQL 数据库连接db, err := sql.Open("mysql", dsn)if err != nil {log.Fatalf("数据库迁移同步操作:数据库连接失败: %v", err) // 记录错误并退出return}defer db.Close() // 确保数据库连接在函数退出时关闭log.Println("数据库迁移同步操作:开始执行数据库迁移。")// 设置 Goose 数据库迁移工具的方言goose.SetDialect("mysql")// 执行数据库迁移if err := goose.Up(db, "migrations"); err != nil {log.Fatalf("数据库迁移同步操作:数据库迁移失败: %v", err) // 记录迁移失败的错误return} else {log.Println("数据库迁移同步操作:数据库已成功迁移到最新版本。")}version, err := goose.GetDBVersion(db)log.Println("数据库迁移同步操作:当前数据库版本为:", version)log.Println("数据库迁移同步操作:数据库迁移和查询操作完成。")
}func main() {// 调用数据库迁移函数migrateDatabase()
}
2. 核心步骤
  1. 打开数据库连接:通过 sqlx 或标准的 sql.Open 打开 MySQL 数据库连接。
  2. 设置 Goos 方言:告诉 goose 使用 MySQL 数据库。
  3. 执行迁移:使用 goose.Up() 方法执行迁移操作,goose.GetDBVersion 检查当前数据库的迁移版本。
  4. 错误处理和日志:对每个步骤都添加详细的错误处理和日志,确保在生产环境中能够快速定位问题。

7. 运行迁移

main() 函数中调用 migrateDatabase(),程序会自动执行数据库的迁移操作。

go run main.go

这将会执行位于 migrations 目录下的 SQL 文件,并根据版本顺序自动更新数据库表。如果迁移执行成功,日志会输出成功信息;如果失败,则会输出详细的错误信息。

运行结果:

2025/01/15 14:27:18 app.go:81: 数据库迁移同步操作:开始执行数据库迁移。
2025/01/15 14:27:18 log.go:29: OK    00001_add_table.sql
2025/01/15 14:27:19 log.go:29: OK    00002_alter_table.sql
2025/01/15 14:27:19 log.go:29: OK    00003_delete_table.sql
2025/01/15 14:27:19 log.go:30: goose: no migrations to run. current version: 3
2025/01/15 14:27:19 app.go:91: 数据库迁移同步操作:数据库已成功迁移到最新版本。
2025/01/15 14:27:19 app.go:95: 数据库迁移同步操作:当前数据库版本为: 3
2025/01/15 14:27:19 app.go:96: 数据库迁移同步操作:数据库迁移和查询操作完成。

8. 最佳实践

  • 版本控制:在团队开发中,确保所有的迁移文件都通过版本控制工具(如Git)进行管理。这样可以避免迁移文件丢失或冲突。

  • 迁移顺序:保持迁移文件的顺序,goose 会根据文件名中的时间戳自动排序。

  • 回滚迁移:在开发过程中,使用 goose down 来回滚不需要的迁移版本,确保数据库表结构可以回到之前的版本。

  • 数据库备份:在执行数据库迁移之前,特别是在生产环境中,务必备份数据库,以防止因迁移失败导致的数据丢失。

9. 附加

migrations 目录下创建以下SQL文件,进行不同版本SQL脚本的测试。

00002_alter_table.sql

-- +goose Up
CREATE TABLE demo5 (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL,age INT NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);ALTER TABLE demo1ADD COLUMN `test` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '测试字段' AFTER `created_at`;UPDATE demo1 SET age = 31 WHERE name = 'Alice';

00003_delete_table.sql

-- +goose Up
DROP TABLE IF EXISTS demo1;
DROP TABLE IF EXISTS demo2;
DROP TABLE IF EXISTS demo3;
DROP TABLE IF EXISTS demo4;
DROP TABLE IF EXISTS demo5;

goose_db_version

成功运行程序后,会自动在数据库生成数据库表goose_db_version,用来记录每个版本执行情况,如果修改某个版本SQL,需删除对应执行记录,重新运行程序!!!

在这里插入图片描述

10. 总结

本文介绍了如何将 goose 集成到 go-zero 框架中,通过数据库迁移管理 MySQL 数据库的版本控制。在实际项目中,使用 goose 可以帮助你轻松管理数据库架构的变更,确保数据库的版本一致性,并且在团队开发中减少冲突。

希望本教程能帮助你更好地理解和使用 goosego-zero,构建高效且可维护的数据库管理系统。

11. 拓展

如果是Java项目,请使用Flyway实现。
SpringBoot或者SpringCloud项目整合Flyway实现数据库版本管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/2361.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day 27 日志文件(枚举,时间函数),目录io,多文件管理

0## 1.获得当前时间 # include <stdio.h> #include <stdlib.h> #include <time.h>int main() {struct tm* ptm;time_t sec time(NULL);ptm localtime(&sec);printf("%d-%d-%d %d:%d:%d\n",ptm->tm_year1900,ptm->tm_mon1,ptm->tm_…

使用Flink-JDBC将数据同步到Doris

在现代数据分析和处理环境中&#xff0c;数据同步是一个至关重要的环节。Apache Flink和Doris是两个强大的工具&#xff0c;分别用于实时数据处理和大规模并行处理&#xff08;MPP&#xff09;SQL数据库。本文将介绍如何使用Flink-JDBC连接器将数据同步到Doris。 一、背景介绍…

【python】OpenCV—Local Translation Warps

文章目录 1、功能描述2、原理分析3、代码实现4、效果展示5、完整代码6、参考 1、功能描述 利用液化效果实现瘦脸美颜 交互式的液化效果原理来自 Gustafsson A. Interactive image warping[D]. , 1993. 2、原理分析 上面描述很清晰了&#xff0c;鼠标初始在 C&#xff0c;也即…

灵活妙想学数学

灵活妙想学数学 题1&#xff1a;海星有几只&#xff1f; 一共有12只海洋生物&#xff0c;分别是5只脚的海星&#xff0c;8只脚的章鱼和10只脚的鱿鱼&#xff0c;这些海洋动物的脚一共有87只&#xff0c;每种生物至少有1只&#xff0c;问海星有几只&#xff1f; 解&#xff1a…

STM32-笔记40-BKP(备份寄存器)

一、什么是BKP&#xff08;备份寄存器&#xff09;&#xff1f; 备份寄存器是42个16位的寄存器&#xff0c;可用来存储84个字节的用户应用程序数据。他们处在备份域里&#xff0c;当VDD电源被切断&#xff0c;他们仍然由VBAT维持供电。当系统在待机模式下被唤醒&#xff0c;或…

Sprint Boot教程之五十八:动态启动/停止 Kafka 监听器

Spring Boot – 动态启动/停止 Kafka 监听器 当 Spring Boot 应用程序启动时&#xff0c;Kafka Listener 的默认行为是开始监听某个主题。但是&#xff0c;有些情况下我们不想在应用程序启动后立即启动它。 要动态启动或停止 Kafka Listener&#xff0c;我们需要三种主要方法…

编译pytorch——cuda-toolkit-nvcc

链接 https://blog.csdn.net/wjinjie/article/details/108997692https://docs.nvidia.com/cuda/cuda-installation-guide-linux/#switching-between-driver-module-flavorshttps://forums.developer.nvidia.com/t/can-not-load-nvidia-drivers-on-ubuntu-22-10/239750https://…

如何发布自己的第一个Chrome扩展程序

如何发布自己的Chrome扩展程序 只需要六步即可完成Chrome扩展程序的发布 &#xff08;1&#xff09;首先打开google chrome 应用商城注册开发者账号的页面 &#xff08;2&#xff09;现在进行一个绑卡支付5美元的一次性注册费用即可。【不知道如何绑卡的支付的&#xff0c;文…

SpringBoot入门实现简单增删改查

本例子的依赖 要实现的内容 通过get、post、put和delete接口,对数据库中的trade.categories表进行增删改查操作。 目录结构 com.test/ │ ├── controller/ │ ├── CateController.java │ ├── pojo/ │ ├── dto/ │ │ └── CategoryDto.java │ ├─…

electron 如何申请 Mac 系统权限

对于一些使用 Electron开发的app, 需要获取一些系统权限,比如录屏权限, 获取摄像头权限,麦克风等等,类似于以下界面: 那么Electron App 应该如何申请呢? 首先我们明确一下macOS中基础权限的分类,可以分为以下几种: 隐私权限(Private Permissions) : <!-- entitlements.ma…

浅谈云计算02 | 云计算模式的演进

云计算计算模式的演进 一、云计算计算模式的起源追溯1.2 个人计算机与桌面计算 二、云计算计算模式的发展阶段2.1 效用计算的出现2.2 客户机/服务器模式2.3 集群计算2.4 服务计算2.5 分布式计算2.6 网格计算 三、云计算计算模式的成熟与多元化3.1 主流云计算服务模式的确立3.1.…

An FPGA-based SoC System——RISC-V On PYNQ项目复现

本文参考&#xff1a; &#x1f449; 1️⃣ 原始工程 &#x1f449; 2️⃣ 原始工程复现教程 &#x1f449; 3️⃣ RISCV工具链安装教程 1.准备工作 &#x1f447;下面以LOCATION代表本地源存储库的安装目录&#xff0c;以home/xilinx代表在PYNQ-Z2开发板上的目录 ❗ 下载Vivad…

AI智能体实战|使用扣子Coze搭建AI智能体,看这一篇就够了(新手必读)

有朋友看到我使用Coze搭建的AI智能体蛮实用的&#xff0c;也想自己尝试一下。那今天我就分享一下如何使用Coze&#xff08;扣子&#xff09;搭建AI智能体&#xff0c;手把手教学&#xff0c;流程超级详细&#xff0c;学会了的话&#xff0c;欢迎分享转发&#xff01; 一、搭建A…

.NET8.0多线程编码结合异步编码示例

1、创建一个.NET8.0控制台项目来演示多线程的应用 2、快速创建一个线程 3、多次运行程序&#xff0c;可以得到输出结果 这就是多线程的特点 - 当多个线程并行执行时&#xff0c;它们的具体执行顺序是不确定的&#xff0c;除非我们使用同步机制&#xff08;如 lock、信号量等&am…

nginx 实现 正向代理、反向代理 、SSL(证书配置)、负载均衡 、虚拟域名 ,使用其他中间件监控

我们可以详细地配置 Nginx 来实现正向代理、反向代理、SSL、负载均衡和虚拟域名。同时&#xff0c;我会介绍如何使用一些中间件来监控 Nginx 的状态和性能。 1. 安装 Nginx 如果你还没有安装 Nginx&#xff0c;可以通过以下命令进行安装&#xff08;以 Ubuntu 为例&#xff0…

《数据思维》之数据可视化_读书笔记

文章目录 系列文章目录前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 数据之道&#xff0c;路漫漫其修远兮&#xff0c;吾将上下而求索。 一、数据可视化 最基础的数据可视化方法就是统计图。一个好的统计图应该满足四个标准&#xff1a;准确、有…

Linux之进程

Linux之进程 一.进程进程之形ps命令进程状态特殊进程孤儿进程守护进程 进程创建之创建子进程进程特性优先级进程切换&#xff08;分时操作系统&#xff09; 二.环境变量三.进程地址空间四.进程终止&进程等待五.进程替换六.自定义shell 本篇博客希望简略的介绍进程&#xff…

漫话架构师|什么是系统架构设计师(开篇)

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 关注犬余&#xff0c;共同进步 技术从此不孤单

在AI智能中有几种重要的神经网络类型?6种重要的神经网络类型分享!

神经网络今天已经变得非常流行&#xff0c;但仍然缺乏对它们的了解。一方面&#xff0c;我们已经看到很多人无法识别各种类型的神经网络及其解决的问题&#xff0c;更不用说区分它们中的每一个了。其次&#xff0c;在某种程度上更糟糕的是&#xff0c;当人们在谈论任何神经网络…

业务幂等性技术架构体系之消息幂等深入剖析

在系统中当使用消息队列时&#xff0c;无论做哪种技术选型&#xff0c;有很多问题是无论如何也不能忽视的&#xff0c;如&#xff1a;消息必达、消息幂等等。本文以典型的RabbitMQ为例&#xff0c;讲解如何保证消息幂等的可实施解决方案&#xff0c;其他MQ选型均可参考。 一、…