以声明方式将 SQL 模式应用于 table 的最简单方法?
Simplest method for declaratively applying a SQL schema to a table?
目标:我正在寻找一种声明和重复table 方式来“应用”SQL table 模式到数据库
我试过的
下面是一个 SQL 脚本,它可以执行我想要的操作(根据我对 MySQL 的肤浅知识和一些手动测试,我可以做到最好):
- 如果 table 不存在,则创建它
- 如果 table 确实存在,它确保它具有所需的架构
-- create table
create table if not exists `EntryType` (
`EntryCode` varchar(2) primary key,
`Name` varchar(256) not null
) engine = InnoDB default charset = utf8mb4;
-- modify table
alter table `EntryType`
engine = InnoDB,
character set utf8mb4;
alter table `EntryType`
modify `EntryCode` varchar(2),
drop primary key,
add primary key (`EntryCode`);
alter table `EntryType`
modify `Name` varchar(256) not null;
这种方法的问题
- 重复:重复列定义、引擎和字符集两次
- 费力:制作这些查询并在每次添加或修改 table 时手动测试它们需要花费大量时间
- 命令式:从根本上说,这是一种命令式的方法来处理一些应该是声明式的东西
问题:是否有一些安全的方法可以声明性地“应用”table 模式?
- 幂等性:可以以完全相同的结束状态应用任意次数
- 无论table是否已经存在
都有效
- 无论table是否已经包含数据
都有效
- 无论是否存在约束和对其他 tables
的外键引用都有效
首选项:
- 纯 SQL 解决方案是理想的
- 可靠且易于使用的 CLI 解决方案会起作用
- 也接受相对简单的手写 SQL 或 Node.js 解决方案
正如 Bill Karwin, the Skeema.io 所建议的那样,CLI 最终在一些简单的测试中运行良好。
文档没有很好地指导您完成设置过程,因此我在此处捕捉到了我的想法。
首次架构提取
从 the github repo releases page 下载 ZIP 文件并解压缩。
将 skeema
二进制文件放在项目的某处。在我的项目根目录中,我把
它位于 bin
文件夹中,因此从项目根目录开始,路径为 ./bin/skeema
.
然后,确保您的 MySQL 数据库是 运行ning 并且您有连接信息。我的 运行 在本地 127.0.0.1
,端口 3306
(MySQL 默认值,所以我不必输入)。
从项目根目录,我输入了以下命令,通过获取数据库模式的当前状态来初始化事物。
./bin/skeema init -h 127.0.0.1 -u root -p --schema=MyDB -d schemas
一些细节:
- 我使用
--schema=MyDB
选项只跟踪一个数据库。如果您将其遗漏,它将跟踪它找到的所有数据库。
-d schemas
选项表示将配置和架构文件存储在 schemas
目录中。
- 使用
-p
选项,它会在 运行 执行命令后提示您输入密码。
然后它会连接到并检查您的数据库,创建 schemas
目录,并在其中写入一些代表当前模式状态的文件。您会注意到数据库中每个 table 都有一个 .skeema
配置文件和一个 .sql
文件。
配置调整
然后我进入 schemas/.skeema
配置文件并将 [production]
部分重命名为 [development]
因为这实际上是一个开发实例。通过这样做,我必须在每个命令中指定 development
,因为 skeema
假定 production
作为默认值。
[可选,仅限 Node.js 项目] skeema
命令旨在 运行 来自包含 .skeema
配置文件的文件夹,但我不我不想担心这个,所以我在我的 Node.js package.json
文件中创建了一个脚本,基本上每次都为我做这个。
{
"scripts": {
"skeema": "cd schemas && ../bin/skeema"
},
}
现在我可以从项目根目录(或项目中的任何其他位置)键入以下内容:
npm run skeema
第一个架构更改
在 schemas/.skeema
配置文件中,我做了一些更改以更正设置这些 table 时的字符编码错误:
- 已将
default-character-set=utf8
更改为 default-character-set=utf8mb4
- 已将
default-collation=utf8_general_ci
更改为 default--collation=utf8mb4_unicode_ci
我还在 .sql
个文件中添加了一个新列:
CREATE TABLE `EntryType` (
`EntryCode` varchar(2) NOT NULL,
`Name` varchar(256) NOT NULL,
`Foo` varchar(3), -- new column
PRIMARY KEY (`EntryCode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
推动架构更改
第一步是查看是否存在架构差异:
npm run skeema diff development
输出应该是您所做的架构更改,例如:
2020-07-02 19:32:14 [INFO] Generating diff of 127.0.0.1:3306 MyDB vs
/Users/chriscalo/Projects/my-project/schemas/*.sql
-- instance: 127.0.0.1:3306
USE `MyDB`;
ALTER TABLE `EntryType` ADD COLUMN `Foo` varchar(3) DEFAULT NULL;
2020-07-02 19:32:15 [INFO] 127.0.0.1:3306 MyDB: diff complete
然后推送架构更改:
yarn run skeema push development
就是这样!
目标:我正在寻找一种声明和重复table 方式来“应用”SQL table 模式到数据库
我试过的
下面是一个 SQL 脚本,它可以执行我想要的操作(根据我对 MySQL 的肤浅知识和一些手动测试,我可以做到最好):
- 如果 table 不存在,则创建它
- 如果 table 确实存在,它确保它具有所需的架构
-- create table
create table if not exists `EntryType` (
`EntryCode` varchar(2) primary key,
`Name` varchar(256) not null
) engine = InnoDB default charset = utf8mb4;
-- modify table
alter table `EntryType`
engine = InnoDB,
character set utf8mb4;
alter table `EntryType`
modify `EntryCode` varchar(2),
drop primary key,
add primary key (`EntryCode`);
alter table `EntryType`
modify `Name` varchar(256) not null;
这种方法的问题
- 重复:重复列定义、引擎和字符集两次
- 费力:制作这些查询并在每次添加或修改 table 时手动测试它们需要花费大量时间
- 命令式:从根本上说,这是一种命令式的方法来处理一些应该是声明式的东西
问题:是否有一些安全的方法可以声明性地“应用”table 模式?
- 幂等性:可以以完全相同的结束状态应用任意次数
- 无论table是否已经存在 都有效
- 无论table是否已经包含数据 都有效
- 无论是否存在约束和对其他 tables 的外键引用都有效
首选项:
- 纯 SQL 解决方案是理想的
- 可靠且易于使用的 CLI 解决方案会起作用
- 也接受相对简单的手写 SQL 或 Node.js 解决方案
正如 Bill Karwin, the Skeema.io 所建议的那样,CLI 最终在一些简单的测试中运行良好。
文档没有很好地指导您完成设置过程,因此我在此处捕捉到了我的想法。
首次架构提取
从 the github repo releases page 下载 ZIP 文件并解压缩。
将 skeema
二进制文件放在项目的某处。在我的项目根目录中,我把
它位于 bin
文件夹中,因此从项目根目录开始,路径为 ./bin/skeema
.
然后,确保您的 MySQL 数据库是 运行ning 并且您有连接信息。我的 运行 在本地 127.0.0.1
,端口 3306
(MySQL 默认值,所以我不必输入)。
从项目根目录,我输入了以下命令,通过获取数据库模式的当前状态来初始化事物。
./bin/skeema init -h 127.0.0.1 -u root -p --schema=MyDB -d schemas
一些细节:
- 我使用
--schema=MyDB
选项只跟踪一个数据库。如果您将其遗漏,它将跟踪它找到的所有数据库。 -d schemas
选项表示将配置和架构文件存储在schemas
目录中。- 使用
-p
选项,它会在 运行 执行命令后提示您输入密码。
然后它会连接到并检查您的数据库,创建 schemas
目录,并在其中写入一些代表当前模式状态的文件。您会注意到数据库中每个 table 都有一个 .skeema
配置文件和一个 .sql
文件。
配置调整
然后我进入 schemas/.skeema
配置文件并将 [production]
部分重命名为 [development]
因为这实际上是一个开发实例。通过这样做,我必须在每个命令中指定 development
,因为 skeema
假定 production
作为默认值。
[可选,仅限 Node.js 项目] skeema
命令旨在 运行 来自包含 .skeema
配置文件的文件夹,但我不我不想担心这个,所以我在我的 Node.js package.json
文件中创建了一个脚本,基本上每次都为我做这个。
{
"scripts": {
"skeema": "cd schemas && ../bin/skeema"
},
}
现在我可以从项目根目录(或项目中的任何其他位置)键入以下内容:
npm run skeema
第一个架构更改
在 schemas/.skeema
配置文件中,我做了一些更改以更正设置这些 table 时的字符编码错误:
- 已将
default-character-set=utf8
更改为default-character-set=utf8mb4
- 已将
default-collation=utf8_general_ci
更改为default--collation=utf8mb4_unicode_ci
我还在 .sql
个文件中添加了一个新列:
CREATE TABLE `EntryType` (
`EntryCode` varchar(2) NOT NULL,
`Name` varchar(256) NOT NULL,
`Foo` varchar(3), -- new column
PRIMARY KEY (`EntryCode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
推动架构更改
第一步是查看是否存在架构差异:
npm run skeema diff development
输出应该是您所做的架构更改,例如:
2020-07-02 19:32:14 [INFO] Generating diff of 127.0.0.1:3306 MyDB vs
/Users/chriscalo/Projects/my-project/schemas/*.sql
-- instance: 127.0.0.1:3306
USE `MyDB`;
ALTER TABLE `EntryType` ADD COLUMN `Foo` varchar(3) DEFAULT NULL;
2020-07-02 19:32:15 [INFO] 127.0.0.1:3306 MyDB: diff complete
然后推送架构更改:
yarn run skeema push development
就是这样!