m_shige1979のささやかな抵抗と欲望の日々

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

PrismaでDBのhasOneを試す

前の記事

m-shige1979.hatenablog.com

今回

f:id:m_shige1979:20211123190202p:plain

外部キーの定義って

後付けや変更ができないのかな? 普段SQLを使うことが多かったので今回prisma migrate devでエラーでできないから分かっていない・・・

設定したもの

prisma/schema.prisma

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

// ER図作成用
generator erd {
  provider = "prisma-erd-generator"
  output   = "../doc/ERD.md"
}

// ユーザーデータ管理用
model User {
  // ID
  id    Int     @id @default(autoincrement())
  // メールアドレス
  email String  @unique
  // 氏名
  name  String?
  // 年齢
  age   Int?

  // 登録日時
  createdAt DateTime @default(now()) @map("created_at")
  // 更新日時
  updatedAt DateTime @default(now()) @map("updated_at")

  // プロフィール(One to One)
  profile Profile?
  // 記事(One to Many)
  posts   Post[]

  // テーブルの物理名
  @@map("users")
}

// プロフィール管理用
model Profile {
  // ID
  id       Int    @id @default(autoincrement())
  // ニックネーム
  nickName String @map("nick_name")

  // 登録日時
  createdAt DateTime @default(now()) @map("created_at")
  // 更新日時
  updatedAt DateTime @default(now()) @map("updated_at")

  // 親テーブルの関連づけ
  userId Int  @unique
  user   User @relation(fields: [userId], references: [id])

  // テーブルの物理名
  @@map("profile")
}

// 記事管理用
model Post {
  // ID
  id    Int    @id @default(autoincrement())
  // タイトル
  title String @map("title")
  // 登録日時
  createdAt DateTime @default(now()) @map("created_at")
  // 更新日時
  updatedAt DateTime @default(now()) @map("updated_at")
  
  // 親テーブルの関連づけ
  userId Int
  user   User @relation(fields: [userId], references: [id])

  // テーブルの物理名
  @@map("posts")
}

migrate後のCREATE文

CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `users_email_key` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `posts` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `userId` int NOT NULL,
  PRIMARY KEY (`id`),
  KEY `posts_userId_fkey` (`userId`),
  CONSTRAINT `posts_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

データ取得方法

基本は前回と同じ、今回は1対多のため、関連テーブルの条件絞り込みが可能

    const user3 = await prisma.user.findFirst({
        where: {
            name: 'hoge1'
        },
        include: {
            profile: {
                select: {
                    nickName: true,
                    createdAt: true,
                },
            },
            posts: {
                select: {
                    title: true
                },
                where: {
                    title: "test1"
                }
            }
        },
    })    
    console.log("case3: ", user3)

配下を全件取得した場合

  id: 16,
  email: 'hoge1@example.com',
  name: 'hoge1',
  age: 20,
  createdAt: 2021-11-23T09:58:03.729Z,
  updatedAt: 2021-11-23T09:58:03.729Z,
  profile: {
    id: 5,
    nickName: 'aaaa',
    createdAt: 2021-11-23T09:58:03.729Z,
    updatedAt: 2021-11-23T09:58:03.729Z,
    userId: 16
  },
  posts: [
    {
      id: 1,
      title: 'test1',
      createdAt: 2021-11-23T09:58:03.729Z,
      updatedAt: 2021-11-23T09:58:03.729Z,
      userId: 16
    },
    {
      id: 2,
      title: 'test2',
      createdAt: 2021-11-23T09:58:03.729Z,
      updatedAt: 2021-11-23T09:58:03.729Z,
      userId: 16
    },
    {
      id: 3,
      title: 'test3',
      createdAt: 2021-11-23T09:58:03.729Z,
      updatedAt: 2021-11-23T09:58:03.729Z,
      userId: 16
    }
  ]
}

一部のみ取得した場合

case3:  {
  id: 16,
  email: 'hoge1@example.com',
  name: 'hoge1',
  age: 20,
  createdAt: 2021-11-23T09:58:03.729Z,
  updatedAt: 2021-11-23T09:58:03.729Z,
  profile: { nickName: 'aaaa', createdAt: 2021-11-23T09:58:03.729Z },
  posts: [ { title: 'test1' } ]
}

所感

ある程度のことはやってくれるイメージ
外部キーのこともあるから頻繁にデータ構造が変わる場合や複雑なSQLがある場合は不向き
次は多対多group by辺りを見てみる

できたもの

github.com

PrismaでDBのhasOneを試す

Prisma

www.prisma.io

hasOneについて

2つのテーブルが1対1、または0の関係のリレーショナル構造のこと

イメージ

f:id:m_shige1979:20211123095306p:plain

Prismaでの定義の方法

prisma/schema.prisma

// ユーザーデータ管理用
model User {
  // ID
  id    Int     @id @default(autoincrement())
  // メールアドレス
  email String  @unique
  // 氏名
  name  String?
  // 年齢
  age   Int?

  // 登録日時
  createdAt DateTime @default(now()) @map("created_at")
  // 更新日時
  updatedAt DateTime @default(now()) @map("updated_at")

  // プロフィール(One to One)
  profile Profile?

  // テーブルの物理名
  @@map("users")
}

// プロフィール管理用
model Profile {
  // ID
  id       Int    @id @default(autoincrement())
  // ニックネーム
  nickName String @map("nick_name")

  // 登録日時
  createdAt DateTime @default(now()) @map("created_at")
  // 更新日時
  updatedAt DateTime @default(now()) @map("updated_at")

  // 親テーブルの関連づけ
  userId Int  @unique
  user   User @relation(fields: [userId], references: [id])

  // テーブルの物理名
  @@map("profile")
}

親モデルへの追加定義

  // プロフィール(One to One)
  profile Profile?

これを追加することで関連するモデルが1または0の状態となる

子モデルへの追加定義

  // 親テーブルの関連づけ
  userId Int  @unique
  user   User @relation(fields: [userId], references: [id])

紐付け用のカラムを追加し親と関連づける

マイグレーション後のCREATE文

CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  PRIMARY KEY (`id`),
  UNIQUE KEY `users_email_key` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `profile` (
  `id` int NOT NULL AUTO_INCREMENT,
  `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `userId` int NOT NULL,
  `nick_name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `profile_userId_key` (`userId`),
  CONSTRAINT `profile_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

データ処理

親のみ取得

    const user1 = await prisma.user.findFirst({
        where: {
            name: 'hoge1'
        },
    })    
    console.log("case1: ", user1)

親子のデータを同時に取得

    const user2 = await prisma.user.findFirst({
        where: {
            name: 'hoge1'
        },
        include: {
            profile: true,
        },
    })    
    console.log("case2: ", user2)

子のデータを一部のみ取得

    const user3 = await prisma.user.findFirst({
        where: {
            name: 'hoge1'
        },
        include: {
            profile: {
                select: {
                    nickName: true,
                    createdAt: true,
                },
            },
        },
    })    
    console.log("case3: ", user3)

子のデータより親を引き出す

    const profile1 = prisma.profile.findFirst({
        where: {
            nickName: 'aaaa'
        },
    });
    const user4 = await profile1.user();
    profile1.then((result) => {
        console.log("case4: ", result, user4);
    })

case1:  {
  id: 10,
  email: 'hoge1@example.com',
  name: 'hoge1',
  age: 20,
  createdAt: 2021-11-23T01:14:46.450Z,
  updatedAt: 2021-11-23T01:14:46.450Z
}
case2:  {
  id: 10,
  email: 'hoge1@example.com',
  name: 'hoge1',
  age: 20,
  createdAt: 2021-11-23T01:14:46.450Z,
  updatedAt: 2021-11-23T01:14:46.450Z,
  profile: {
    id: 3,
    nickName: 'aaaa',
    createdAt: 2021-11-23T01:14:46.450Z,
    updatedAt: 2021-11-23T01:14:46.450Z,
    userId: 10
  }
}
case3:  {
  id: 10,
  email: 'hoge1@example.com',
  name: 'hoge1',
  age: 20,
  createdAt: 2021-11-23T01:14:46.450Z,
  updatedAt: 2021-11-23T01:14:46.450Z,
  profile: { nickName: 'aaaa', createdAt: 2021-11-23T01:14:46.450Z }
}
case4:  {
  id: 3,
  nickName: 'aaaa',
  createdAt: 2021-11-23T01:14:46.450Z,
  updatedAt: 2021-11-23T01:14:46.450Z,
  userId: 10
} {
  id: 10,
  email: 'hoge1@example.com',
  name: 'hoge1',
  age: 20,
  createdAt: 2021-11-23T01:14:46.450Z,
  updatedAt: 2021-11-23T01:14:46.450Z
}

親だけ削除とかはできんかった

多分、リレーションの設定で削除も連動するようにしてないせいと思うが seedファイルを改修する際に、削除⇨作成したらエラーになる。 ちょっと気をつけよう

できたやつ

github.com

参考

Relation queries (Concepts) | Prisma Docs

ExpressとPrismaでREST API実装1

前々回

m-shige1979.hatenablog.com

前回

m-shige1979.hatenablog.com

今回は

NodeJSのフレームワークExpressPrismaを使用したREST APIを実装
今回は触りだけなのでシンプルな構成

参考資料

github.com

これ

src/index.ts

import express from 'express'

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

// express server
const app = express()

// リクエストデータをjsonで受け取れるようにする
app.use(express.json())
app.use(express.urlencoded({ extended: true }));

// ユーザー一覧
app.get('/users', async (req, res) => {
    // ユーザー一覧を取得
    const users = await prisma.user.findMany({})

    // 返却
    res.json(users)
})

// ユーザー詳細
app.get('/user/:id', async (req, res) => {
    // パラメータを取得
    const { id } = req.params;
    // ユーザー情報を取得
    const user = await prisma.user.findFirst({
        where: {
            id: Number(id)
        }
    })

    // 返却
    res.json(user)
})

// ユーザー登録
app.post('/user', async (req, res) => {
    // パラメータ取得
    console.log(req.body);
    const { email, name } = req.body;

    // この辺でバリデーション

    // 登録
    const user = await prisma.user.create({
        data: {
            "email": email,
            "name": name
        }
    })

    // 返却
    res.json({
        "status": 0,
        "result": user
    })
})

// ユーザー更新
app.put('/user/:id', async (req, res) => {
    // パラメータ取得
    console.log(req.body);
    const { id } = req.params;
    const { email, name } = req.body;

    // この辺でバリデーション


    // 登録
    const user = await prisma.user.update({
        where: {
            "id": Number(id)
        },
        data: {
            "email": email,
            "name": name,
            "updatedAt": new Date()
        }
    })

    // 返却
    res.json({
        "status": 0,
        "result": user
    })
})


// ユーザー削除
app.delete('/user/:id', async (req, res) => {
    // パラメータを取得
    const { id } = req.params;
    // ユーザー情報を削除
    const user = await prisma.user.deleteMany({
        where: {
            id: Number(id)
        }
    })

    // 返却
    // 返却
    res.json({
        "status": 0,
        "result": user
    })
})


// server listen
const server = app.listen(3000)

prismaオブジェクト配下から各モデルを引っ張ってくる

リレーションでhasOnehasManyの構成をしていてついでに取得とかもやってくれるよう 今回はデータ考えてなかったので実装はしていないです。

VSCodeで書くとエラーが検知しやすい

Typescriptの拡張かPrismaの拡張か判断に困ることはありますが、 「そんな項目ないよ」的な指摘をピンポイントで出してくれるので 誤りに早く気づく

ts-node-devを利用したホットリロード

なんか初回しか検知しないのでおかしいと思って起動時のパラメータを追加 最終的にはこんな感じ

package.json

  "scripts": {
    "start": "ts-node-dev --respawn --debug --exit-child src/index.ts",
  },

今回のもの

github.com

PrismaでSeedでデータを投入する

前回

m-shige1979.hatenablog.com

Prisma

www.prisma.io

今回

Seedでデータを投入する

やり方

なんかprisma/seed.tsを作成して、データを登録する処理を書くみたい

やってみる

プロジェクト構成は前回のまま

package.json

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@prisma/client": "^3.5.0",
    "@types/express": "^4.17.13",
    "@types/node": "^16.11.9",
    "express": "^4.17.1",
    "ts-node": "^10.4.0",
    "typescript": "^4.5.2"
  },
  "devDependencies": {
    "prisma": "^3.5.0"
  }
}

スクリプト作成

参考になりそうなもの

github.com

prisma/seed.ts

import { PrismaClient, Prisma } from '@prisma/client'
const prisma = new PrismaClient()

// モデル投入用のデータ定義
const userData: Prisma.UserCreateInput[] = [
    {
        name: 'hoge1',
        email: 'hoge1@example.com',
    },
    {
        name: 'hoge2',
        email: 'hoge2@example.com',
    },
    {
        name: 'hoge3',
        email: 'hoge3@example.com',
    },
]

const transfer = async () => {
    const users = [];
    for (const u of userData) {
        const user = prisma.user.create({
            data: u,
        })
        users.push(user);
    }
    return await prisma.$transaction(users);
}

// 定義されたデータを実際のモデルへ登録する処理
const main = async () => {
    console.log(`Start seeding ...`)

    await transfer();

    console.log(`Seeding finished.`)
}

// 処理開始
main()
    .catch((e) => {
        console.error(e)
        process.exit(1)
    })
    .finally(async () => {
        await prisma.$disconnect()
    })

seedコマンドを追加

package.json

以下を追加

  "prisma": {
    "seed": "ts-node prisma/seed.ts"
  }

実行

app# npx prisma db seed
Environment variables loaded from .env
Running seed command `ts-node prisma/seed.ts` ...
Start seeding ...
Seeding finished.

🌱  The seed command has been executed.
app#

f:id:m_shige1979:20211120212558p:plain

OK

所感

seed.tsに共通処理を記載して、あとはデータやテーブルは別ファイルで管理すればそこまで肥大化しないのでは と思っている。 次はそうだな…expressと連携してAPI経由でデータを取得するところをやってみよう。

github

github.com

Typescriptで動作するDBのマイグレーションツールPrismaを触ってみた

Prisma

www.prisma.io

いくつかマイグレーションツール探していてなんか良いのがなかった

最悪、sqlでどうにかしようかなぁと思っていた。

お試し環境

node16のdockerコンテナ

docker-compose

version: "3"

services:

  # backend
  backedn:
    # コンテナ名
    container_name: node-dev
    # build
    image: node:16
    # コンテナの中に入る
    tty: true
    # 他のコンテナ起動後に起動するように制御
    depends_on:
      - db
    # ボリューム
    volumes:
      - "./app"
    # WORKDIR
    working_dir: /app
    # 環境変数
    environment:
      TZ: "Asia/Tokyo"

  # DBサーバ
  db:
    # コンテナ名
    container_name: db
    # build
    image: mysql
    # 環境設定
    environment:
      TZ: Asia/Tokyo
      MYSQL_ROOT_USER: root
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: sample1
      MYSQL_USER: app
      MYSQL_PASSWORD: password
    # コンテナの中に入る
    tty: true
    # ボリューム
    volumes:
      - mysql_data:/var/lib/mysql
    # ポート開放
    ports:
      - 3306:3306

# 名前付きボリュームをdockerホストの管理下で作成
volumes:
  #
  mysql_data: {}

build, up

docker-compose build
docker-compose run --rm backend bash

# node -v
v16.13.0
# npm -v
8.1.0
#

手順

プロジェクト初期化

# npm init -y
Wrote to /app/package.json:

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}


#

関連パッケージをインストール

npm install --save typescript
npm install --save @types/node
npm install --save ts-node
npx tsc --init
npm install --save express
npm install --save @types/express
npm install --save-dev prisma
npm install --save @prisma/client

# cat package.json
{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@prisma/client": "^3.5.0",
    "@types/express": "^4.17.13",
    "@types/node": "^16.11.9",
    "express": "^4.17.1",
    "ts-node": "^10.4.0",
    "typescript": "^4.5.2"
  },
  "devDependencies": {
    "prisma": "^3.5.0"
  }
}
#

prismaの初期化

npx prisma init

.
|-- package-lock.json
|-- package.json
|-- prisma
|   `-- schema.prisma
`-- tsconfig.json

.envprisma/schema.prismaが生成されるため、DBの情報を修正する

.env

DATABASE_URL="mysql://root:password@db:3306/sample1"

prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

モデルを作成する

prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?

  @@map("users")
}

マイグレーション実行

npx prisma migrate dev --name init

↓ 新規の場合はmigrationsディレクトリが作成され、SQLファイルができる

migrations/
  └─ 20211120075456_init/
    └─ migration.sql

DB構成

f:id:m_shige1979:20211120165744p:plain

適当なデータを準備

INSERT INTO users (
    `email`, `name`
) VALUES 
    ('test1@test.com', 'test1'),
    ('test2@test.com', 'test2'),
    ('test3@test.com', 'test3')
;

サンプルコード

index.ts

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

async function main() {
    const allUsers = await prisma.user.findMany({})
    console.dir(allUsers, { depth: null })
}

main()
    .catch((e) => {
        throw e
    })
    .finally(async () => {
        await prisma.$disconnect()
    })

 npx ts-node index.ts

[
  { id: 1, email: 'test1@test.com', name: 'test1' },
  { id: 2, email: 'test2@test.com', name: 'test2' },
  { id: 3, email: 'test3@test.com', name: 'test3' }
]

うん、いい感じ

所感

最初はSequelizeでいく予定でしたがテーブル名を別名で定義するところとかがうまくできなくて 困っていました。 こちらは結構わかりやすい感じ ゴリゴリ対応は最悪SQL直がきにしかないかもですがシンプルな構成の場合はやりやすいかも 次はSeedを試す

参考

Prisma - Next-generation Node.js and TypeScript ORM for Databases

次世代の Node.js ORM 、Prisma を試す

5分で終わるPrisma 2 Tutorial - valid,invalid

AWSでEC2を踏み台にしてPrivate SubnetのRDSへ接続

イメージ

f:id:m_shige1979:20211113145744p:plain

参考ページ

Amazon EC2 を踏み台ホストとして使用して、ローカルマシンからプライベート Amazon RDS DB インスタンスに接続する AWS SSHでEC2踏み台サーバーを経由してRDSに接続 - Qiita AWSのEC2からRDSに接続してmySQLを操作。EC2踏み台サーバー構築メモ|おちゃカメラ。

やり方

ざっくりいうと EC2とRDSを構築するだけ EC2はPublic SubnetへRDSはPrivate Subnetで 特別にEC2でなんかのツールを入れるとかはない

ネットワーク周り

VPC

f:id:m_shige1979:20211113150319p:plain

Public Subnet

f:id:m_shige1979:20211113150508p:plain

Private Subnet

f:id:m_shige1979:20211113150745p:plain

Internet Gateway

f:id:m_shige1979:20211113150858p:plain

ルートテーブル

f:id:m_shige1979:20211113151035p:plain

セキュリティグループ

SSH

f:id:m_shige1979:20211113151243p:plain

MYSQL

f:id:m_shige1979:20211113151458p:plain

EC2設定

無料枠を選択

f:id:m_shige1979:20211113151714p:plain

無料枠を選択2

f:id:m_shige1979:20211113151811p:plain

作成したVPCやサブネットを指定

f:id:m_shige1979:20211113152052p:plain

Private IPを設定

f:id:m_shige1979:20211113152627p:plain

そのまま

f:id:m_shige1979:20211113152712p:plain

タグ名は識別しやすいもの

f:id:m_shige1979:20211113152840p:plain

セキュリティグループはSSHのみ通過

f:id:m_shige1979:20211113153017p:plain

この後にキーペア作る

f:id:m_shige1979:20211113153137p:plain

キーペアをダウンロード

f:id:m_shige1979:20211113153309p:plain

起動完了

f:id:m_shige1979:20211113153427p:plain

キーペアでMacのコマンドより接続

権限変更

mv `pwd`/Downloads/mshige1979-keypair-01.pem `pwd`/.ssh/.
chmod 600 `pwd`/.ssh/mshige1979-keypair-01.pem

接続

% ssh ec2-user@13.231.90.xxx -i `pwd`/.ssh/mshige1979-keypair-01.pem
The authenticity of host '13.231.90.xxx (13.231.90.xxx)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '13.231.90.xxx' (ED25519) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-100-1-168 ~]$

RDS用サブネットグループ

f:id:m_shige1979:20211113155144p:plain

RDS

エンジン

MySQL f:id:m_shige1979:20211113155411p:plain

テンプレート

無料版 f:id:m_shige1979:20211113154713p:plain

設定

f:id:m_shige1979:20211113155551p:plain

VPCは作成したもの

f:id:m_shige1979:20211113155844p:plain

セキュリティグループは作成したMySQL

f:id:m_shige1979:20211113155946p:plain

接続はパスワード

f:id:m_shige1979:20211113160031p:plain

f:id:m_shige1979:20211113161050p:plain

クライアントから接続

ツールはSequel Ace f:id:m_shige1979:20211113161427p:plain ↓ 多分、できた f:id:m_shige1979:20211113161604p:plain

所感

やることが多い・・・ 結構疲れた

Ubuntu20.04にPotreeConverterをインストール

PotreeConverter?なにそれ?

以下とか見てください weare.kyouei38.co.jp

超簡単にいうと

iphone proとかなんか性能が良いカメラで3Dデータを撮影したデータをWebで見れるようにするためのツールです。

環境

色々頑張ったんですけど以下になった

Ubuntu:20.04(dockerコンテナです) gcc、g++は9.4あたり(apt-getで取得できるやつ) cmake:3.21.4 PotreeConverter:2.1(多分最新)

一応それっぽい環境

github.com

手順

apt-getパッケージインストール

apt-get  update   -y \
  && apt-get install  -y tzdata build-essential libtiff-dev libgeotiff-dev \
      libboost-all-dev libssl-dev \
      wget gcc g++ libc6-dev-i386 git

cmake install

cd /usr/local/src/ \
  && wget https://github.com/Kitware/CMake/releases/download/v3.21.4/cmake-3.21.4.tar.gz \
  && tar zxf cmake-3.21.4.tar.gz \
  && cd cmake-3.21.4/ \
  && ./bootstrap \
  && make -j4 \
  && make install

TBB

cd /usr/local/src/ \
  && git clone https://github.com/wjakob/tbb.git \
  && cd tbb/build \
  && cmake .. \
  && make \
  && make install \
  && ldconfig

LAS

cd /usr/local/src/ \
  && git clone https://github.com/m-schuetz/LAStools.git \
  && cd LAStools/LASzip \
  && mkdir build \
  && cd build \
  && cmake \
    -DCMAKE_BUILD_TYPE=Release .. \
  && make \
  && make install \
  && ldconfig

PotreeConverter2.1

cd /usr/local/src/ \
  && wget https://github.com/potree/PotreeConverter/archive/refs/tags/2.1.tar.gz \
  && tar zxf 2.1.tar.gz \
  && cd PotreeConverter-2.1 \
  && mkdir build \
  && cd build \
  && cmake \
    -DCMAKE_BUILD_TYPE=Release \
    -DLASZIP_INCLUDE_DIRS=/usr/local/src/LAStools/LASzip/dll \
    -DLASZIP_LIBRARY=/usr/local/src/LAStools/LASzip/build/src/liblaszip.so .. \
  && make \
  && chmod +x ./PotreeConverter \
  && ln -s /usr/local/src/PotreeConverter-2.1/build /opt/PotreeConverter

実行

変換

/opt/PotreeConverter/PotreeConverter \
    /input/scaniverse-20211105-170039.las \
    -o /output/test1 \
    --generate-page test1

# tree /output/test1/ -I libs
/output/test1/
|-- pointclouds
|   `-- test1
|       |-- hierarchy.bin
|       |-- metadata.json
|       `-- octree.bin
`-- test1.html

Potreeで見た感じ

f:id:m_shige1979:20211107155406p:plain 全画面使用されるから埋め込みとかは向いてなさそうな感じ

ちなみに撮影には以下

Scaniverse - LiDAR 3D Scanner

Scaniverse - LiDAR 3D Scanner

  • Toolbox AI
  • 写真/ビデオ
  • 無料
apps.apple.com