3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CloudSpannerでENUMを使う方法

Posted at

背景

CloudSpannerではENUMを使うことができるので使い方を調べてみました〜

ENUM作り方・使い方

CloudSpannerは、基本的にgRPCで構成されているので対応する型を作って登録することができます。
そして、その型をCloudSpanner上でENUMとして使うことができます。下記が手順です。

  1. protoファイル定義
    1. protocコマンド実行
    2. pbファイル生成
  2. DDLファイル作成
  3. gcloudコマンド実行
    1. 引数
      1. DDLファイル or DDL
      2. pbファイル
  4. SQL実行時にENUMと紐づける

protoファイル定義

product.proto
syntax = "proto3";

package product;

enum ProductType {
  HOGE = 0;
  HUGU = 1;
}

protocコマンド実行

protoc --descriptor_set_out=product.pb product.proto

pbファイル爆誕

このファイルを使ってCloudSpannerに適用させていく。

product.pb
K
product.proto	product*%
ProductType	
HOGE	
HUGUbproto3

DDLファイル作成

ENUMを使いたくば CREATE PTORO BUNDLE をCloudSpannerに適用しないといけないらしい。ソースは下記。

そのためDDLファイルを作成した。

product.ddl
CREATE PROTO BUNDLE (
  product.ProductType
);

gcloudコマンド実行

「ddlの適用」と「DDLが登録されているかを確認」をしている。

gcloud spanner databases ddl update hoge-db --instance=hoge-local --ddl-file=/app/cloudspanner/sql/product.ddl --proto-descriptors-file=/app/cloudspanner/product.pb
gcloud spanner databases ddl describe hoge-db --instance=hoge-local

実行結果

Schema updating...
.....done.
CREATE PROTO BUNDLE (
  product.ProductType,
);

CREATE TABLE SchemaMigrations (
  Version INT64 NOT NULL,
  Dirty BOOL NOT NULL,
) PRIMARY KEY(Version);

SQL実行時にENUMとひもづける

cloudspannerを使っているのでwrenchを使いこなそうと思っている。
DB操作クライアント(dbeaver)をつかったDDLの実行は問題なくできたが、ENUMを使っているテーブルはマイグレーション管理ができなくなってしまうという課題感がでてきた。

wrenchでマイグレーションできない

wrenchからマイグレーションファイルを生成して下記のように記述した。

wrenchのマイグレーション実行結果
CREATE TABLE products (
    id INT64 NOT NULL,
    product_type product.ProductType NOT NULL -- product.ProductTypeでエラー
) PRIMARY KEY(id);

-- ↓ 実行時エラー
-- 登録したenumが使えない...
-- Error command: up, version: 1.10.1
--   failed to parse DDL/DML statements: 000001.sql:3: got "product", want scalar type, 000001.sql:1.0: unknown DML statement

failed to parse DDL/DML statements

wrench/pkg/spanner/migration.goddlToStatements でこけていることがわかった。

ddlToStatements

内部的にspansqlというものを使っているらしい。

処理の流れ

余談

ちなみにSpanSQLにENUM自体は次のリリースで対応されるらしい。

ENUMに対応したPR

リリースタグ

ENUM使わないなら、どう制約かける?

  • アプリケーション内でチェックをする
  • SQL文にCHECK制約を使う
CREATE TABLE products (
    id STRING(36) NOT NULL,
    product_type STRING(10) NOT NULL,
    CHECK (product_type IN ('HOGE', 'HUGU'))
) PRIMARY KEY(id);
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?