惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
Recorded Future
Recorded Future
B
Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
GbyAI
GbyAI
IT之家
IT之家
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
S
SegmentFault 最新的问题
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
罗磊的独立博客
MongoDB | Blog
MongoDB | Blog
The Cloudflare Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
腾讯CDC
小众软件
小众软件
博客园 - 三生石上(FineUI控件)
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
Martin Fowler
Martin Fowler
P
Proofpoint News Feed
月光博客
月光博客
博客园_首页
C
Check Point Blog
宝玉的分享
宝玉的分享
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Tenable Blog
Vercel News
Vercel News
SecWiki News
SecWiki News
Security Latest
Security Latest
Microsoft Security Blog
Microsoft Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
阮一峰的网络日志
阮一峰的网络日志
Hacker News - Newest:
Hacker News - Newest: "LLM"
Google Online Security Blog
Google Online Security Blog
N
News and Events Feed by Topic
Y
Y Combinator Blog
U
Unit 42
The Register - Security
The Register - Security
云风的 BLOG
云风的 BLOG
K
Kaspersky official blog
WordPress大学
WordPress大学
Blog — PlanetScale
Blog — PlanetScale
N
Netflix TechBlog - Medium
Jina AI
Jina AI

Razeen`s Blog

Let's Encrypt 推出 Gen Y 根证书架构:揭示 Web PKI 的五大未来趋势 通过 Wi-Fi 自动备份你的 iPhone 到 Nas 管理培训感悟:从技术视角看管理之路 UPS 一拖多:保护你的 NAS 和 Linux 服务器 从影音中心到 AI 助手:我的50款 Homelab 服务清单 从SSL证书有效期将缩短到47天聊开去 部署一个自己的 Running Page 谈谈特斯拉 Model Y 用车一年的感受和费用分析 弃用 Disqus 评论,使用自建 Waline 使用 Prometheus 和 Grafana 搭建你的证书监控面板 服务器迁移记:一次磁盘换板引发的Linux分区与挂载的学习 改善信息来源, 利用 RSS 高效获取资讯 (RSShub + Reeder5 + WeWe RSS) 多种 Docker 镜像拉取解决方案与实践 App分享 | AppCleaner - Mac上的卸载神器 Azure OpenAI API 申请和使用 如何开通 OneKey 虚拟信用卡,并充值消费 如何拥有一个可长期在国内使用的国外手机号码 分享开通 ChatGPT Plus 过程 如何开通 Depay 虚拟信用卡,并充值消费 如何开通欧易Web3钱包, 交易入账 如何5分钟内1块钱注册 ChatGPT 如何注册美区的 Apple ID (2023年/无需科学上网) NAS折腾记(11): NASTool3.0体验和降级 NAS折腾记(10): Docker版本的NASTool配置 NAS折腾记(9): NASTool与微信交互,微信发送消息远程下载电影【多图】 NAS折腾记(8):群晖安装 NASTool 实现影音半自动化【多图】 内网穿透(2):Tailscale 组网实现内网穿透,操作简单,无成本 内网穿透(1):总结了11中内网穿透的方式,总有一种适合你 NAS折腾记(7):从零开始设置(黑)群晖系统 NAS折腾记(6):黑群晖系统安装好后怎么洗白? NAS折腾记(5):群晖硬盘休眠设置与分析 NAS折腾记(4): 20分钟手把手带你完美安装 DS918+ 黑群晖7.1.1 NAS折腾记(3):NAS 装机 NAS折腾记(2):B360-ITX 双M.2 双2.5G网口 6 SATA主版 开箱 NAS折腾记(1):328元的4盘位Nas机箱开箱 Openwrt + Clash 全局科学上网 Newifi3 刷入 OpenWrt 固件 v21.02 利用 Markdown 画一些流程图、时序图、甘特图等 Homelab(8): 搭建自用 Gitlab 与 Docker 仓库 Nginx Tcp 转发保留客户端真实 IP (PROXY Protocol) Homelab (7):IPSec VPN(基于证书认证)客户端设置 Homelab (6): 基于自签发证书的 IPSec VPN 搭建 Homelab (5): DDNS 动态域名解析 Homelab (4): Linux 服务器基础环境准备 Homelab (3): 整体网络与基础硬件介绍 Go学习笔记(十)老项目迁移 go module 大型灾难记录 Github Actions 初体验之自动化部署 Hexo 博客 记一次 Nginx DNS 缓存导致转发问题 Homelab (2): 电信悦me网关修改桥接模式,路由器拨号 Homelab (1):5分钟上手黑群晖 NAS 终极 Bash 脚本指南 Typora 自动上传图片到七牛云 Ubuntu 20.04 LTS 有线网卡驱动安装 折腾 Ubuntu 20.04 LTS 开发环境 Go学习笔记(九) 计时器的生命周期[译] 利用 git hook 规范你的代码与 commit message 规范 git commit message 与自动化版本控制 超详细 vim 配置 (with MacVim) Golang 中的 RESTful API 最佳实践 折腾服务器(开篇) 我的第一台个人服务器 Newifi3 实现低成本家庭级科学上网 Go学习笔记(八) | 使用 os/exec 执行命令 如何用 Go 调用 Windows API Mac OS 自动根据 WI-FI 名字改变网络位置 关于 Docker 清理 MIME Types 速查表 Go学习笔记(七) | 理解OAuth 2.0并实现一个客户端 我又又又把博客迁移了 Go学习笔记(六) | 使用swaggo自动生成Restful API文档 Go学习笔记(五) | 使用代码片段(snippets)提高编码效率 书单 - 2018 IPFS 初体验,利用 IPFS 托管你的静态网站 记一次 PostgreSQL LIKE 索引优化,联合字段 LIKE 查询优化。 Disqus 添加有趣的 Reactions 的功能 TLS 1.3 详解 (RFC 8446解读) gRPC在Go中的使用(三)gRPC实现TLS加密通信与流模式 gRPC在Go中的使用(二)gRPC实现简单通讯 gRPC在Go中的使用(一)Protocol Buffers语法与相关使用 CentOS 安装 tshark 抓包工具 Go学习笔记(四) | win上使用VSCode搭建Go开发环境 日常 Postgres 数据库点滴记录 简单了解 PKCS 规范 美食篇 | DIY戚风蛋糕(烤箱做蛋糕) Go学习笔记(三) | 怎么写Go基准测试(性能测试) TLS1.3正式更新,为Nginx添加TLS1.3的支持 一次诡异的数据库删除 GitHub Pages自定义域名开启HTTPS 证书透明度是什么?它是怎么工作的? Go学习笔记(二) | 我对 recover 的一点误解 搭建证书透明度(certificate-transparency)日志服务之从入门到放弃 修复远程登陆 Centos 时,出现 UTF-8 Warning HTTPS篇之SSL握手过程详解 Go学习笔记(一) | postgres与golang点点滴滴 AWS 命令行界面(aws-cli)从安装到快速上手 数字证书分类及怎么区分各类数字证书 常用 linux 命令小结(一)文件目录操作 云服务器搭建 hexo 博客,git hooks自动更新 SSH 免密登陆, SSH Config 配置 Golang CGO Mac 交叉编译 Windows 开始使用Ghost
使用 goose 让数据库迁移更加轻松
2017-03-29 · via Razeen`s Blog

在开发到发布的过程中,数据库的迁移是一件较为繁琐的事,而goose的出现,让数据库的迁移变得很轻松。

我们只需要简单的一句goose up 就能将数据库重新部署,一句goose down 就能将原有的数据库清除,是不是感觉很easy!

安装

go get bitbucket.org/liamstask/goose/cmd/goose

安装完成后可以运行goose 查看是否安装成功。

如果提示 command not found: goose 你可以查看一下你的$GOPATH/bin 下有没有goose的binary文件,如果有那么安装成功了,只是PATH中没把这个路径添加进去。

设置~/.bash_profileGOPATH/bin 加入PATH即可,类似如下。

export GOPATH=/Users/razeen/go   
export GOBIN=/Users/razeen/go/bin
export PATH=$PATH:$GOBIN

配置

在安装完成后,你就可以在你的项目中配置goose了。

1.首先,在你的项目下需要一个db的文件夹,并且在文件夹的下面有一个数据库配置文件dbconf.yml(当然,该文件夹 也可以用-path来指定,只要该文件夹下有数据库配置文件dbconf.yml即可)。

2.配置dbconf.yml的内容。 一个简单的dbconf.yml文件的格式如下所示:

development:
    driver: postgres
    open: user=liam dbname=tester sslmode=disable

这里的driveropen是直接通过go的database/sql 库去与数据库交互。driver即数据库驱动,常见的驱动(sqlite,mysql,postgres)database/sql都支持,其他驱动稍后也有介绍。 open即数据库连接参数,常见的数据库操作实例如下:

# sqlite 配置
driver : sqlite
open : ./my_test_sqlite.sdb  # sqlite数据库路径

# postgres 配置
driver : postgres
open : user=postgres password=123456 dbname=test sslmode=disable 

# mysql 配置
driver : mysql
open : user:password@tcp(localhost:3306)/dbname?charset=utf8

而这里development 是你可用自己可以指定的一个环境名字。假如你在开发的时候和正式发布的时候数据库的环境并不相同,你就可以很轻松的用这个关键来分开部署。

实例如下,在开发过程中使用development标识,在生产环境中用production标识,两种情况的数据库环境不相同:

development:
    driver: postgres
    open: user=postgres  dbname=test sslmode=disable 
production:
    driver: postgres
    open:  user=myusername password=112233 dbname=mytest sslmode=disable 

上面例子很明显的看到,两个环境下的数据库连接是不同的。在具体的使用时我们就可以用-env来制定具体的环境。有关其使用,后面有介绍。

其他驱动

除了常见的sqlite,mysql,postgres三个驱动外,goose还可以使用一些支持database/sql的驱动。这时就需要一个import pathknown dialect 了,如下所示:

customdriver:
    driver: custom
    open: custom open string
    import: github.com/custom/driver
    dialect: mysql

因为在SQL中编写的迁移由goose二进制直接执行,所以只有编译到goose中的驱动程序才可以用于这些迁移。

使用

在完成文件夹的创建以及数据库配置文件的参数设置后,就可已使用goose迁移你的数据库了。

Create

创建一个迁移语句,你可以选择使用go或者sql来创建。 例如,我需要创建一个基础的数据库脚本。

# 使用golang迁移
goose create basic_go 
# 创建成功, 输出
goose: created goose/db/migrations/20161130232822_basic_go.go
# 或者使用 sql脚本
goose create basic_sql sql
# 创建成功, 输出
goose: created goose/db/migrations/20161130232902_basic_sql.sql

执行goose 相关命令的目录与db目录应该同一层。

我们可以查看文件。创建的go脚本如下:

package main

import (
	"database/sql"
)

// Up is executed when this migration is applied
func Up_20161129103859(txn *sql.Tx) {

}

// Down is executed when this migration is rolled back
func Down_20161129103859(txn *sql.Tx) {

}

创建的sql脚本如下:

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied


-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back

数据库迁移语句就可以写在Up与Down有关区域内。

在其中写上需要的数据库迁移的操作。如下:

  • File:goose/db/migrations/20161130232822_basic_go.go
package main

import (
	"database/sql"
	"fmt"
)

// Up is executed when this migration is applied
func Up_20161130232822(txn *sql.Tx) {
	fmt.Println("Up Out ...")
}

// Down is executed when this migration is rolled back
func Down_20161130232822(txn *sql.Tx) {
	fmt.Println("Down Out ...")
}
  • File: goose/db/migrations/20161130232902_basic_sql.sql

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
CREATE TABLE IF NOT EXISTS test (
	id serial,
	con text
);

-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back
DROP TABLE test;

sql语句以分号结束,不然可能无法识别。

Up

执行goose up就是执行脚本Up区域的内容,所有可用的迁移脚本都将被执行。

在上面的例子中,执行goose up得到结果:

goose: migrating db environment 'development', current version: 0, target: 20161130232902
Up Out ...
OK    20161130232822_basic_go.go
OK    20161130232902_basic_sql.sql

到数据库查看,表格已经创建好了。当然,上面说的指定环境,此时就可以指定了,如果不指定默认就是development,在真正产的时候,我们可以如下使用:

goose -env production up

# 结果
goose: migrating db environment 'production', current version: 0, target: 20161130232902
Up Out ...
OK    20161130232822_basic_go.go
OK    20161130232902_basic_sql.sql

在实际生产的时候,我们也可以指定执行某一个脚本,如下所示:

# 再创建一个脚本
goose create add_cloumn sql

# 结果
goose: created /Users/trustasia/dev/go/src/demo_mi/goose/db/migrations/20161130235504_add_cloumn.sql

# 写上迁移语句
-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
ALTER TABLE test ADD  new_con text;

-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back
ALTER TABLE test DROP COLUMN new_con;

# 指定脚本迁移
goose goose up add_cloumn
# 结果
goose: migrating db environment 'development', current version: 20161130232902, target: 20161130235504
OK    20161130235504_add_cloumn.sql

Down

执行goose down 向前回滚一个版本。

在上面的例子中,我们回滚。

goose down
# 结果
goose: migrating db environment 'development', current version: 20161130235504, target: 20161130232902
OK    20161130235504_add_cloumn.sql

我们也可以指定环境,或指定脚本来回滚。

# 指定生产环境回滚
goose  -env production down
# 结果
goose: migrating db environment 'production', current version: 20161130232902, target: 20161130232822
OK    20161130232902_basic_sql.sql

# 制定版本回滚
goose down basic_sql  
# 结果
goose: migrating db environment 'development', current version: 20161130232902, target: 20161130232822
OK    20161130232902_basic_sql.sql

redo

向上回滚一个版本,然后重新执行一次上次的操作。

goose redo

goose: migrating db environment 'development', current version: 20161130232822, target: 0
Down Out ...
OK    20161130232822_basic_go.go
goose: migrating db environment 'development', current version: 0, target: 20161130232822
Up Out ...
OK    20161130232822_basic_go.go

status

查看当前所有的迁移执行状态。

goose status
goose: status for environment 'development'
    Applied At                  Migration
    =======================================
    Thu Dec  1 09:25:17 2016 -- 20161130232822_basic_go.go
    Pending                  -- 20161130232902_basic_sql.sql
    Pending                  -- 20161130235504_add_cloumn.sql

# 查看production环境下的
goose -env production status
goose: status for environment 'production'
    Applied At                  Migration
    =======================================
    Wed Nov 30 23:51:00 2016 -- 20161130232822_basic_go.go
    Pending                  -- 20161130232902_basic_sql.sql
    Pending                  -- 20161130235504_add_cloumn.sql

dbversion

查看当前数据库版本。

goose dbversion
goose: dbversion 20161130232822

总结与注意事项

    1. up,down区域脚本对应goose up,goose down;
    1. 可用-env指定数据库环境,-path指定包含数据库信息的路径;
    1. 数据库语句以分号介绍,不可缺少;
    1. 复杂的函数语句写在-- +goose StatementBegin-- +goose StatementEnd之间,例下面的如创建函数。
-- +goose Up
-- +goose StatementBegin
CREATE OR REPLACE FUNCTION histories_partition_creation( DATE, DATE )
returns void AS $$
DECLARE
  create_query text;
BEGIN
  FOR create_query IN SELECT
      'CREATE TABLE IF NOT EXISTS histories_'
      || TO_CHAR( d, 'YYYY_MM' )
      || ' ( CHECK( created_at >= timestamp '''
      || TO_CHAR( d, 'YYYY-MM-DD 00:00:00' )
      || ''' AND created_at < timestamp '''
      || TO_CHAR( d + INTERVAL '1 month', 'YYYY-MM-DD 00:00:00' )
      || ''' ) ) inherits ( histories );'
    FROM generate_series( $1, $2, '1 month' ) AS d
  LOOP
    EXECUTE create_query;
  END LOOP;  -- LOOP END
END;         -- FUNCTION END
$$
language plpgsql;
-- +goose StatementEnd