一个基于增量同步数据库结构的工具 - Goose

嗨!大家好,我是波罗学。本文是 Golang 三方库推荐第四篇,系列查看:Golang 三方库。

上篇文章,我讨论了数据库 schema 同步的两种方式:增量和差异。今天,推荐一个基于 Go 实现的增量同步数据库 schema 的工具库 - goose。我不知道其他人的情况,我工作的很长一段时间内,接触到的这类工具都是采用增量方式实现的。

让我们开始正文吧!

为什么选择 Goose?

首先,市场上已经存在了那么多数据库迁移工具,如 Flyway、Liquibase 和 Alembic。它们一般也都是采用增量方式管理数据库迁移。

在这众多选项中,为什么要用 Goose 呢?我觉得最主要原因就是,它简单易上手,我们能迅速掌握并开始迁移任务。

快速一览 Goose 功能特性

多数据库支持:Goose 可与多种数据库系统一起使用,包括但不限于 MySQL, PostgreSQL, SQLite, 和SQL Server。

向前和向后迁移:支持向前(up)和向后(down)迁移,不仅可以通过迁移来更新数据库结构,还可以回滚到之前的状态。

编程语言灵活性:Goose 最初是用 Go 编写的,但它支持在迁移文件中使用纯 SQL,这就拓宽了它的目标用户群体。

命令行接口:Goose 提供了一个简单的命令行接口(CLI),使执行迁移操作更简单直观。这篇文章中的演示都是基于命令接口。

版本控制:Goose 的每次迁移都会记录版本号,使数据库的版本控制变得清晰。版本号是基于时间生成的。

环境配置:Goose 本身是不支持的,我简单改造了下,,基于它写了 shell 脚本,让它支持根据不同的环境(如开发、测试、生产)配置和应用不同配置,实现不同迁移策略。

安装

安装 Goose 相当简单。首先,确保你已经安装了 Go。然后,通过下面命令安装 Goose:

$ go install github.com/pressly/goose/v3/cmd/goose@latest

这条命令会将 goose 命令安装到 GOBIN 目录下。

或者 MacOS:

$ brew install goose

到此,就顺利安装成功了。

演示案例

接下来,我将通过案例逐步演绎 Goose 的使用,基于 Goose cli 命令管理这些 SQL 脚本。

创建迁移

假设,现在要为一个项目添加一个用户表。第一步就是创建一个 SQL 迁移脚本。

迁移脚本创建,命令如下:

$ goose create create_users_table sql
2024/02/20 17:52:58 Created new file: 20240220095258_create_users_table.sql

命令的最后一个参数 sql 表示创建的 SQL 脚本,如果没有这个参数,默认创建的是 Go 脚本。

默认脚本内容:

-- +goose Up
-- +goose StatementBegin
SELECT 'up SQL query';
-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
SELECT 'down SQL query';
-- +goose StatementEnd

这个示例脚本包含了两部分:同步(Up)和回滚(Down)。其中的 - +goose Up 标记了接下来的 SQL 语句是用于同步迁移的。而 -- +goose Down 标记了接下来的 SQL 语句是用于回滚的。

我们用创建 users 表的 SQL 替换其中的 SELECT 'up SQL query,用删除 users 表的 SQL 替换 SELECT 'down SQL query

-- +goose Up
-- +goose StatementBegin
CREATE TABLE users (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(64) NOT NULL,
    password CHAR(32) NOT NULL,
    email VARCHAR(255) UNIQUE  NOT NULL
);
-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
DROP TABLE if EXISTS users;
-- +goose StatementEnd

我们使用 Goose 的 up 执行同步迁移操作。

$ goose mysql "root:password@/core?parseTime=true" up
2024/02/20 18:07:57 OK   20240220095258_create_users_table.sql (21.8ms)
2024/02/20 18:07:57 goose: successfully migrated database to version: 20240220095258

这条命令会应用所有未执行的迁移脚本,创建数据库 users 表结构。Goose 会跟踪每次迁移的状态,确保每个迁移只被执行一次。

如果打开数据库,查看表的创建结果,你会发现,数据库中多了一个非我们预期内的表 - goose_db_version。这个表就是 goose 用来追踪每次迁移的状态信息。

mysql> show tables;
+------------------+
| Tables_in_core   |
+------------------+
| goose_db_version |
| users            |
+------------------+
2 rows in set (0.01 sec)
mysql> select * from goose_db_version;
+----+----------------+------------+---------------------+
| id | version_id     | is_applied | tstamp              |
+----+----------------+------------+---------------------+
|  1 |              0 |          1 | 2024-02-20 10:07:57 |
|  2 | 20240220095258 |          1 | 2024-02-20 10:07:57 |
+----+----------------+------------+---------------------+

如果想回滚之前创建的表,使用命令 down 即可回滚。

$goose mysql "root:password@/core?parseTime=true" down
2024/02/20 18:21:38 OK   20240220095258_create_users_table.sql (16.7ms)

Goose 其他命令一览

Goose 其他的一些命令如下所示。当使用 Goose 进行数据库迁移时,你可以使用它们。

Commands:
 up-by-one       Migrate the DB up by 1
 up-to VERSION   Migrate the DB to a specific VERSION
 down-to VERSION Roll back to a specific VERSION
 redo            Re-run the latest migration
 reset           Roll back all migrations
 status          Dump the migration status for the current DB
 version         Print the current version of the database
 fix             Apply sequential ordering to migrations
 validate        Check migration files without running them

快速一览:

  1. up-by-one: 逐步迁移数据库,只迁移一个版本。
  2. up-to VERSION: 迁移数据库到指定的版本。
  3. down-to VERSION: 回滚数据库到指定的版本。
  4. redo: 重新运行最新的迁移。
  5. reset: 回滚所有的迁移,删除所有已应用的迁移。
  6. status: 输出当前数据库迁移的状态。它会显示已生效版本和未生效版本。
  7. version: 打印当前数据库的版本号。
  8. fix: 将迁移文件转换为顺序号顺序。确保按照顺序号的执行。
  9. validate: 检查迁移文件的有效性,但不运行它们。

无版本控制迁移

Goose 除支持版本控制管理迁移脚本,我们还可以完全去掉版本,传递选项 --no-versioning 给命令即可。

为什么要这个能力?官方文章中提供的使用场景,如某些情况下,我们只是想插入一些数据,或者开发测试时修正一些问题,就可以通过方式处理。

.
└── schema
    ├── migrations
    │   ├── 00001_add_users_table.sql
    │   ├── 00002_add_posts_table.sql
    │   └── 00003_alter_users_table.sql
    └── seed
        ├── 00001_seed_users_table.sql
        └── 00002_seed_posts_table.sql

将要版本控制的放在 migrations 目录下,而无版本控制的插入数据的脚本存放在 seed 目录。

演示命令,如下所示:

goose -dir ./schema/migrations up
goose -dir ./schema/seed -no-versioning up

管理多环境

前面的演示,总是要在命令行上指定数据库类型和连接参数才能连接真实环境数据库,即麻烦又容易出错。

$ goose mysql "root:password@/core?parseTime=true" up

好在,Goose 提供了通过环境变量配置数据库的连接信息。

# 数据库类型,如 MySQL、PostgreSQL 等
GOOSE_DRIVER=DRIVER 
# 连接信息,如 MySQL root:password@/core?parseTime=true
GOOSE_DBSTRING=DBSTRING 

现在就可以直接执行如 goose upgoose down 等命令。

另外,我为了让 Goose 支持多环境配置,开发了一个简单的 shell 脚本,从配置中获取环境信息,设置到这两个环境变量上。

配置的形式如下:

dev:
    driver: mysql
    open: user:password@/dbname?parseTime=true
test:
    driver: mysql
    open: user:password@/test_dbname?parseTime=true
prod:
    driver: mysql
    open: user:password@/prod_dbname?parseTime=true

在上面的例子中,我们定义了三个环境:devtestprod。每个环境都有自己的数据库连接字符串。

支持环境管理的命令脚本源码如下所示,我将其命名为 goosem

#!/bin/bash

assert_installed_cmd() {
    if ! command -v $1 &> /dev/null
    then
        echo -e "$1 could not be found. Please install $1:\n\t$2"
        exit 1
    fi
}

assert_installed_cmd yq "yq" "brew install yq"
assert_installed_cmd goose "goose" "brew install goose"

if [ "$#" -lt 1 ]; then
    echo "Usage: $0 <environment> [goose commands]"
    exit 1
fi

ENV=$1
CONFIG_FILE="dbconf.yml"

DRIVER=$(yq e ".$ENV.driver" $CONFIG_FILE)
DBSTRING=$(yq e ".$ENV.open" $CONFIG_FILE)

if [ "$DRIVER" == "null" ] || [ "$DBSTRING" == "null" ]; then
    echo "Configuration for environment '$ENV' not found."
    exit 1
fi

export GOOSE_ENV=$ENV
export GOOSE_DRIVER=$DRIVER
export GOOSE_DBSTRING=$DBSTRING

shift

goose "$@"

现在,我们可以通过如下命令使用 Goose 了。

goosem dev up

这个脚本里面依赖了一个 yaml 解析工具,名为 yq,要提前安装下:

$ brew install yq

现在,Goose 就有了支持多环境的能力了。非常简单。

如果你有按环境执行不同的迁移脚本的需求,可通过使用 Go 迁移脚本,在其中添加环境检查的逻辑来实现这一点。

举例来说,你可以在 Go 迁移脚本中检查是否是 prod 环境决定是否执行某部分迁移逻辑。

if os.Getenv("GOOSE_ENV") == "prod" {
  // ...
}

这有个前提,你要熟悉 GO 这门编程语言。

最后

本文介绍了一个 GO 开发的基于增量实现数据结构迁移的工具 goose,还基于 shell 让它能进行多环境管理,有趣的,哈哈。本文主要是通过 SQL 脚本演示,Goose 本身也是支持 Go 脚本管理 Schema 的,灵活度更高。

下篇文章,我将介绍另一个基于差异管理数据库 schema 的工具,依然是用 Go 实现的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图像处理基础——频域、时域

傅里叶分析不仅仅是一个数学工具&#xff0c;更是一种可以彻底颠覆一个人以前世界观的思维模式。 一、什么是频域 时域 时域是信号在时间轴随时间变化的总体概括&#xff1b;频域是把时域波形的表达式做傅立叶等变化得到复频域的表达式&#xff0c;所画出的波形就是频谱图&a…

Android Termux安装MySQL并实现公网远程连接本地数据库

文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备&#xff0c;尽管最初并非设计为服务器&#xff0c;但是随着技术的进步我们可以将Android配置为生产力工具&#xff0c;变成一个随身…

pix2pix-zero

pix2pix-zero&#xff1a;零样本图像到图像转换 论文介绍 Zero-shot Image-to-Image Translation 关注微信公众号: DeepGoAI 项目地址&#xff1a;https://github.com/pix2pixzero/pix2pix-zero 论文地址&#xff1a;https://arxiv.org/abs/2302.03027 本文介绍了一种名为…

live555学习 - 环境准备

环境&#xff1a;Ubuntu 16.04.7 ffmpeg-6.1 1 代码下载 最新版本&#xff1a; http://www.live555.com/liveMedia/public/ 历史版本下载 https://download.videolan.org/pub/contrib/live555/ 选择版本live.2023.01.19.tar.gz ps&#xff1a;没有选择新版本是新版本在…

深入理解计算机系统笔记

1.1 嵌套的数组 当我们创建数组的数组时&#xff0c;数组分配和引用的一般原则也是成立的。 例如&#xff0c;声明 int A[5][3]; 等价于下面的声明 typedef int row3_t[3]; row3_t A[5] 要访问多维数组的元素&#xff0c;编译器会以数组起始为基地址&#xff0c; (可能需…

MQTT协议解析:揭秘固定报头、可变报头与有效载荷的奥秘

MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;是一种轻量级的通讯协议&#xff0c;常用于远程传感器和控制设备的通讯。MQTT协议基于发布/订阅模式&#xff0c;为大量计算能力有限且工作在低带宽、不可靠网络环境中的设备…

【报名指南】2024年第九届数维杯数学建模挑战赛报名全流程图解

1.官方报名链接&#xff1a; 2024年第九届数维杯大学生数学建模挑战赛http://www.nmmcm.org.cn/match_detail/32 2.报名流程&#xff08;电脑与手机报名操作流程一致&#xff09; 参赛对象为在校专科生、本科生、研究生&#xff0c;每组参赛人数为1-3人&#xff08;指导老师不…

RDD简介与基础编程

1. 什么是RDD&#xff1f; RDD&#xff08;Resilient Distributed Dataset&#xff09;叫做弹性分布式数据集&#xff0c;是Spark中最基本的数据处理模型。在代码中&#xff0c;RDD是一个抽象类&#xff0c;他代表着一个弹性的、不可变的、可分区的、里面的元素可并行计算的集…

附加Numpy数组

参考&#xff1a;Append Numpy Array 引言 在数据科学和机器学习领域&#xff0c;处理大规模数据集是一项重要且常见的任务。为了高效地处理数据&#xff0c;numpy是一个非常强大的Python库。本文将详细介绍numpy中的一个重要操作&#xff0c;即如何附加&#xff08;append&a…

常用字符函数和字符串函数的了解和模拟实现

前言 字符函数和字符串函数都是在编程中用来处理字符和字符串的函数。 字符函数是用来处理单个字符的函数&#xff0c;比如查找、替换、转换大小写、比较等操作。常用的字符函数包括&#xff1a; isalpha()&#xff1a;判断一个字符是否为字母&#xff1b;isdigit()&#xf…

图像分割 - 查找图像的轮廓(cv2.findContours函数)

1、前言 轮廓,是指图像中或者物体的外边缘线条。在简单的几何图形中,图形的轮廓是由平滑的线条构成,容易被识别。但不规则的图形或者生活中常见的物体轮廓复杂,识别起来比较困难 2、findContours函数 这里先介绍函数的参数,具体的含义会在下面实验中阐述 opencv 提供的轮…

源码框架-​1.Spring底层核心原理解析

目录 Spring中核心知识点: Bean的创建过程 推断构造方法 AOP大致流程 Spring事务 Spring中核心知识点: Bean的生命周期底层原理依赖注入底层原理初始化底层原理推断构造方法底层原理AOP底层原理Spring事务底层原理 ps:这篇文章中都只是大致流程&#xff0c;后续会针对每…

猜测了一个sora模型结构

如果是上述的这种结构&#xff0c;可以确定的是patch 的size &#xff08;一个图像的小片&#xff09;是固定大小的 那么调节一个视觉分辨率大小通过patchs的大小决定。 如图所示可以证明输入的时候图片没有本物理人为的分割为小片&#xff0c;是通过一个模型进行分割为 小片。…

Container killed on request. Exit code is 143

Bug信息 WARN YarnAllocator: Container marked as failed: container_e33_1480922439133_0845_02_000002 on host: hdp4. Exit status: 143. Diagnostics: Container killed on request. Exit code is 143 Container exited with a non-zero exit code 143 Killed by externa…

供应链|NUS覃含章MS论文解读:数据驱动下联合定价和库存控制的近似方法 (二)

编者按 本次解读的文章发表于 Management Science&#xff0c;原文信息&#xff1a;Hanzhang Qin, David Simchi-Levi, Li Wang (2022) Data-Driven Approximation Schemes for Joint Pricing and Inventory Control Models. https://doi.org/10.1287/mnsc.2021.4212 文章在数…

助力智能化农田作物除草,基于YOLOv7【tiny/l/x】不同系列参数模型开发构建农田作物场景下玉米苗、杂草检测识别分析系统

在我们前面的系列博文中&#xff0c;关于田间作物场景下的作物、杂草检测已经有过相关的开发实践了&#xff0c;结合智能化的设备可以实现只能除草等操作&#xff0c;玉米作物场景下的杂草检测我们则少有涉及&#xff0c;这里本文的主要目的就是想要基于YOLOv7系列的模型来开发…

Android14之解决编译报错:bazel: no such file or directory(一百八十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

如何通过代理IP安全使用Linkedln领英?

LinkedIn是跨境外贸必备的拓客工具&#xff0c;世界各地的许多专业人士都使用领英来作为发布和共享内容的主要工具&#xff0c;这使得它成为跨境出海必备的渠道工具。 但是不少做外贸的朋友都知道&#xff0c;领英账号很容易遭遇限制封禁&#xff0c;但如果善用工具&#xff0…

中小型水库安全监测运营解决方案,筑牢水库安全防线

我国水库大坝具有“六多”的特点。第一&#xff0c;总量多。我国现有水库9.8万座&#xff0c;是世界上水库大坝最多的国家。第二&#xff0c;小水库多。我国现有水库中95%的水库是小型水库。第三&#xff0c;病险水库多。 目前&#xff0c;在我国水库管理中&#xff0c;部分地方…

第3届图像处理与媒体计算国际会议(ICIPMC 2024)即将召开!

2024年第3届图像处理与媒体计算国际会议&#xff08;ICIPMC2024&#xff09;将于2024年5月17-19日在中国合肥举行。本次大会由安徽大学、西北工业大学&#xff0c;西北大学和IEEE联合主办。ICIPMC 2024旨在汇集该领域领先的学术科学家、研究人员和学者&#xff0c;并进行交流和…