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.mzph.cn/bicheng/68241.shtml

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

相关文章

JAVA:Spring Boot 集成 JWT 实现身份验证的技术指南

1、简述 在现代Web开发中,安全性尤为重要。为了确保用户的身份,JSON Web Token(JWT)作为一种轻量级且无状态的身份验证方案,广泛应用于微服务和分布式系统中。本篇博客将讲解如何在Spring Boot 中集成JWT实现身份验证…

说一说mongodb组合索引的匹配规则

一、背景 有一张1000多万条记录的大表,需要做归档至历史表,出现了大量慢查询。 查询条件是 "classroomId": {$in: ["xxx", "xxx", ..... "xxx","xxx", "xxx" ] }耗时近5秒,且…

更新java

下载 Java 下载 |神谕 (oracle.com)

CSS3的aria-hidden学习

前言 aria-hidden 属性可用于隐藏非交互内容,使其在无障碍 API 中不可见。即当aria-hidden"true" 添加到一个元素会将该元素及其所有子元素从无障碍树中移除,这可以通过隐藏来改善辅助技术用户的体验: 纯装饰性内容,如…

【Java设计模式-5】装饰模式:给咖啡加点“佐料”

今天咱们要探索一下Java世界里的装饰模式(Decorator Pattern)。为了让这个过程更加生动易懂,咱们就以大家都熟悉的咖啡饮品来举例吧,想象一下,你就是那个咖啡大师,要给顾客调制出各种独特口味的咖啡哦&…

C++(5)

1.运算符重载 头文件 #ifndef MYSTRING_H #define MYSTRING_H#include <iostream> #include <cstring>using namespace std;class myString { private:char *str;//C风格字符串int size0; public:std::string s_str;//转换构造函数myString(const std::string &a…

K8S--配置存活、就绪和启动探针

目录 1 本人基础环境2 目的3 存活、就绪和启动探针介绍3.1 存活探针3.2 就绪探针3.3 启动探针 4 探针使用场景4.1 存活探针4.2 就绪探针4.3 启动探针 5 配置存活、就绪和启动探针5.1 定义存活探针5.2 定义一个存活态 HTTP 请求接口5.3 定义 TCP 的就绪探针、存活探测5.4 定义 g…

【HTML+CSS+JS+VUE】web前端教程-36-JavaScript简介

JavaScript介绍 JavaScript是一种轻量级的脚本语言&#xff0c;所谓脚本语言&#xff0c;指的是它不具备开发操作系统的能力&#xff0c;而是用来编写控制其他大型应用程序的“脚本” JavaScript是一种嵌入式语言&#xff0c;它本身提供的核心语法不算很多 为什么学习JavaScri…

LLM实现视频切片合成 前沿知识调研

1.相关产品 产品链接腾讯智影https://zenvideo.qq.com/可灵https://klingai.kuaishou.com/即梦https://jimeng.jianying.com/ai-tool/home/Runwayhttps://aitools.dedao.cn/ai/runwayml-com/Descripthttps://www.descript.com/?utm_sourceai-bot.cn/Opus Cliphttps://www.opu…

AI多模态论文解读:LLaVA-CoT:让视觉语言模型逐步推理

本文作者&#xff1a;AIGCmagic社区 猫先生 一、简 介 LLaVA-CoT引入了四个不同的阶段&#xff08;摘要、标题、推理和结论&#xff09;&#xff0c;使模型能够独立进行系统化的多阶段推理&#xff0c;显著提高了在推理密集型任务上的准确性。 编译了LLaVA-CoT-100k数据集&am…

分布式缓存redis

分布式缓存redis 1 redis单机&#xff08;单节点&#xff09;部署缺点 &#xff08;1&#xff09;数据丢失问题&#xff1a;redis是内存存储&#xff0c;服务重启可能会丢失数据 &#xff08;2&#xff09;并发能力问题&#xff1a;redis单节点&#xff08;单机&#xff09;部…

《C++11》nullptr介绍:从NULL说起

在C11之前&#xff0c;我们通常使用NULL来表示空指针。然而&#xff0c;NULL在C中有一些问题和限制&#xff0c;这就是C11引入nullptr的原因。本文将详细介绍nullptr的定义、用法和优点。 1. NULL的问题 在C中&#xff0c;NULL实际上是一个整数0&#xff0c;而不是一个真正的…

供应链数字化转型参考大型供应链系统技术架构设计方案

该文介绍了一个大型供应链系统技术架构的设计方案&#xff0c;包括整体设计、核心技术目录和应用案例。设计采用Choerodon微服务框架&#xff0c;关注海量并发、可伸缩性、安全性等方面。同时&#xff0c;方案符合大型企业结构的HR组织架构&#xff0c;支持多级组织架构和角色、…

STM32F1学习——DMA直接存储器存取

一、DMA直接存储器存取 DMA的全称是 Direct Memory Access 直接存储器存取&#xff0c;他可以提供外设和存储器间或存储器和存储器间的高速数据传输&#xff0c;无需CPU的干预。 STM32有12个DMA通道&#xff0c;由DMA1(7个通道组成)和DMA2(5个通道组成)&#xff0c;STM32F103C8…

一个使用 Golang 编写的新一代网络爬虫框架,支持JS动态内容爬取

大家好&#xff0c;今天给大家分享一个由ProjectDiscovery组织开发的开源“下一代爬虫框架”Katana&#xff0c;旨在提供高效、灵活且功能丰富的网络爬取体验&#xff0c;适用于各种自动化管道和数据收集任务。 项目介绍 Katana 是 ProjectDiscovery 精心打造的命令行界面&…

6.2 MySQL时间和日期函数

以前我们就用过now()函数来获得系统时间&#xff0c;用datediff()函数来计算日期相差的天数。我们在计算工龄的时候&#xff0c;让两个日期相减。那么其中的这个now函数返回的就是当前的系统日期和时间。 1. 获取系统时间函数 now()函数&#xff0c;返回的这个日期和时间的格…

用 Python 处理 CSV 和 Excel 文件

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

vulnhub靶场【IA系列】之Tornado

前言 靶机&#xff1a;IA-Tornado&#xff0c;IP地址为192.168.10.11 攻击&#xff1a;kali&#xff0c;IP地址为192.168.10.2 都采用虚拟机&#xff0c;网卡为桥接模式 本文所用靶场、kali镜像以及相关工具&#xff0c;我放置在网盘中&#xff0c;可以复制后面链接查看 htt…

[云讷科技] 用于软件验证的仿真环境

我们使用Pursuit自动驾驶仪为各种场景设计仿真环境&#xff0c;以便用户可以在模拟环境中直接验证他们的软件&#xff0c;无需现场测试。该环境基于Gazebo引擎。 1. 工作区目录 模拟环境的工作区位于提供的U盘中的~/pursuit_space/sitl_space_pursuit中。用户可以按照用户手册…

【Uniapp-Vue3】页面生命周期onLoad和onReady

一、onLoad函数 onLoad在页面载入时触发&#xff0c;多用于页面跳转时进行参数传递。 我们在跳转的时候传递参数name和age: 接受参数&#xff1a; import {onLoad} from "dcloudio/uni-app"; onLoad((e)>{...}) 二、onReady函数 页面生命周期函数中的onReady其…