- 投稿日:2020-05-31T22:03:21+09:00
SQLで時間差を算出する
データが作成された日と更新日との差を取得するために、エラーメッセージが出たときの備忘録。
失敗作
時間差を算出するには
TIMEDIFF
がよいということで、下記のコードで実行。SELECT DATEDIFF(DAY, createTimestamp, updateTimestamp) AS DiffDateこのときのデータの型は
DATETIME
で長さは6と定義したもので、値は2019-08-02 12:53:33.172000
になります。
しかし、上記コードではError Code: 1582 Incorrect parameter count in the call to native function 'DATEDIFF'
のエラー発生。解決策
こちらのサイトでも同じ様な悩みを持った人がいたようです。
DATEDIFF
では2つのパラーメターしか許可されず、日数で返却されるようです。下記のコードで無事解決出来ました。
SELECT DATEDIFF(createTimestamp, updateTimestamp) AS DiffDate;他サイトで、上記3つのパラメータがとれるときと取れない時の違いが分からない点に不安を残しつつ、そのうち解決していきます。
- 投稿日:2020-05-31T21:28:14+09:00
MySQLでよく使う便利なコマンド20選
データベースの一覧
mysql> SHOW DATABASES; +-------------------------+ | Database | +-------------------------+ | information_schema | | mysql | | mysql_rails_development | | mysql_rails_test | | performance_schema | | sys | | tabechoku | | tabechoku_test | +-------------------------+ 8 rows in set (0.00 sec)ログインしているユーザーを確認
mysql> SELECT USER(); +----------------+ | user() | +----------------+ | root@localhost | +----------------+ 1 row in set (0.00 sec)ユーザーの一覧
mysql> SELECT user,host FROM mysql.user; +---------------+-----------+ | user | host | +---------------+-----------+ | hatsu | localhost | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +---------------+-----------+ 4 rows in set (0.00 sec)TIPS
SQL文の末尾を
;
から\G
に変えると縦にデータを並べて表示できるmysql> SELECT user,host FROM mysql.user\G *************************** 1. row *************************** user: hatsu host: localhost *************************** 2. row *************************** user: mysql.session host: localhost *************************** 3. row *************************** user: mysql.sys host: localhost *************************** 4. row *************************** user: root host: localhost 4 rows in set (0.01 sec)現在接続しているクライアントを表示
mysql> SHOW FULL PROCESSLIST\G *************************** 1. row *************************** Id: 68 User: root Host: localhost db: mysql_rails_development Command: Query Time: 0 State: starting Info: SHOW FULL PROCESSLIST 1 row in set (0.00 sec)特定のユーザーの権限を確認
mysql> SHOW GRANTS FOR 'root'@'localhost'; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | | GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+ 2 rows in set (0.00 sec)Statusを確認
mysql> STATUS; -------------- mysql Ver 14.14 Distrib 5.7.29, for osx10.15 (x86_64) using EditLine wrapper Connection id: 68 Current database: Current user: root@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.7.29 Homebrew Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8 Db characterset: utf8 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /tmp/mysql.sock Uptime: 1 day 2 hours 10 min 56 sec Threads: 1 Questions: 2580 Slow queries: 0 Opens: 1585 Flush tables: 1 Open tables: 1050 Queries per second avg: 0.027 --------------MySQLのバージョンを確認
mysql> SELECT VERSION(); +-----------+ | VERSION() | +-----------+ | 5.7.29 | +-----------+ 1 row in set (0.00 sec)使うデータベースを切り替える
mysql> USE mysql_rails_development;テーブル一覧
mysql> SHOW TABLES; +-----------------------------------+ | Tables_in_mysql_rails_development | +-----------------------------------+ | ar_internal_metadata | | articles | | schema_migrations | +-----------------------------------+ 3 rows in set (0.01 sec)テーブル一覧の詳細
ysql> SHOW TABLE STATUS\G *************************** 1. row *************************** Name: ar_internal_metadata Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 1 Avg_row_length: 16384 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2020-05-31 15:02:22 Update_time: 2020-05-31 15:10:26 Check_time: NULL Collation: utf8mb4_general_ci Checksum: NULL Create_options: Comment: *************************** 2. row *************************** Name: articles Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: 1 Create_time: 2020-05-31 15:10:26 Update_time: NULL Check_time: NULL Collation: utf8mb4_general_ci Checksum: NULL Create_options: Comment: 記事 *************************** 3. row *************************** Name: schema_migrations Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 1 Avg_row_length: 16384 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2020-05-31 15:02:22 Update_time: 2020-05-31 15:10:26 Check_time: NULL Collation: utf8mb4_general_ci Checksum: NULL Create_options: Comment: 3 rows in set (0.00 sec)テーブル定義の確認
mysql> SHOW CREATE TABLE articles \G *************************** 1. row *************************** Table: articles Create Table: CREATE TABLE `articles` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL COMMENT 'タイトル', `detail` text COMMENT '本文', `created_at` datetime(6) NOT NULL, `updated_at` datetime(6) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='記事' 1 row in set (0.00 sec)テーブルの各種情報を確認
mysql> SHOW TABLE STATUS LIKE 'articles'\G *************************** 1. row *************************** Name: articles Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: 1 Create_time: 2020-05-31 15:10:26 Update_time: NULL Check_time: NULL Collation: utf8mb4_general_ci Checksum: NULL Create_options: Comment: 記事 1 row in set (0.00 sec)テーブルのカラム一覧
mysql> DESC articles; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | title | varchar(255) | NO | | NULL | | | detail | text | YES | | NULL | | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec)テーブルのIndexを確認
mysql> SHOW INDEX FROM users \G *************************** 1. row *************************** Table: users Non_unique: 0 Key_name: PRIMARY Seq_in_index: 1 Column_name: id Collation: A Cardinality: 101200 Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: Index_comment: *************************** 2. row *************************** Table: users Non_unique: 0 Key_name: index_users_on_email Seq_in_index: 1 Column_name: email Collation: A Cardinality: 101200 Sub_part: NULL Packed: NULL Null: Index_type: BTREE Comment: Index_comment:SELECTの結果をファイルに書き出す
mysql> SELECT * FROM USERS INTO OUTFILE 'users.txt';Auto Commitモードにする/しない
- SQL文を実行した後にすぐにコミットするモード
- デフォルトでは、AutoCommitモードになっている
AutoCommitモードにする
mysql> SET AUTOCOMMIT=1; Query OK, 0 rows affected (0.00 sec)AutoCommitモードを取り消す
mysql> SET AUTOCOMMIT=0; Query OK, 0 rows affected (0.00 sec)テーブルをロックする
- READロック:誰もがテーブルを読み込めるが、誰も書き込みはできない
- WRITEロック:自分だけがそのテーブルを読み書きできる。他のユーザーは読むこともできない
- Lockを外すときは、
UNLOCK TABLES
mysql> LOCK TABLES users READ, items WRITE; mysql> UNLOCK TABLES;前のエラー内容を見る
mysql> SHOW WARNINGS; ERROR 1193 (HY000): Unknown system variable 'AUTOCOMIT'テーブルをコピーする
- souceテーブルの構造、データをコピーしてcopyテーブルを作る
mysql> CREATE TABLE copy SELECT * FROM souce;
- テーブル構造のみをコピー
mysql> CREATE TABLE copy LIKE souce;テーブルが存在したら/しなかったら
テーブルが存在しなかったら作成する
mysql> CREATE TABLE IF NOT EXISTS foo_table;テーブルが存在したら作成する
mysql> CREATE TABLE IF NOT EXISTS foo_table;
- 投稿日:2020-05-31T21:27:06+09:00
Capistrano自動デプロイ設定時(初回)に出たエラー「Mysql2::Error: Table 'users' already exists」の解決方法
アプリを本番環境に上げる際にCapistranoを導入しようとしたら、下記のエラーが出ました。
Mysql2::Error: Table 'users' already exists: CREATE TABLE 'users'
「ユーザーズテープルすでにあるよ」と怒られているようです。
状況を整理
・手動デプロイは上手くいっている。
・Capistranoの【初回デプロイ】(つまりまだ一回も成功していない)でエラーが出た。
・MySQLやusersテーブルについて言及されているので、マイグレーション系のエラーである。どうやら、本番環境下のマイグレーション関係で問題が起きている模様。
解決法
結論、
ローカル環境で修正したマイグレーションが本番環境で反映されてませんでした。[ec2-user@ip <リポジトリ名>] 以下で下記コマンドを打って解決
①DBを削除する
ターミナルRAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop(Railsバージョンによって異なる模様。参考記事参照)
②DBをcreateする
ターミナルrails db:create RAILS_ENV=production
③DBをmigrateするターミナルrails db:migrate RAILS_ENV=production
■ちなみに、①DBを削除するCapistranoの自動デプロイが成功した後であれば、データベースが「current」に入っていると思われるので「current」で削除を行う模様です(試していません)■参考記事
Rails5以降の本番環境でデータベースをresetする方法!
デプロイは難しいですね。ですがコーディングと同様にエラーのたびに理解が深まるので知識が積み重なってく感じがすきです。頑張りましょ〜
- 投稿日:2020-05-31T15:18:12+09:00
Docker mysql sqlファイル実行されない
はじめに
おっちょこちょい事件でした、、、
結論から言うと、コンテナを最初に作成するときにsqlファイル実行されるので、
コンテナ削除までしましょうってことでした!!
コンテナストップまでではなくコンテナ削除まで!
ちなみに、イメージの削除までは行わなくて良いっぽいですね!なので行う処理は以下みたいな感じです!
sqlコンテナ削除で再度コンテナ構築まで
a725b2d62fceは自分のものを
$ docker ps
$ docker stop a725b2d62fce
$ docker rm a725b2d62fce
$ docker-compose up --build -d
sqlコンテナ入る
602a4868b08bは自分のものを
$ docker exec -i -t 602a4868b08b bash
sqlログインする
$ mysql -u root -p
パスワード以下のものならexampleコンテナ入っての確認
$ SHOW DATABASES;
$ use mydb01;
$ SHOW TABLES;
本文引用
When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.
google翻訳
コンテナが初めて起動されると、指定された名前の新しいデータベースが作成され、提供された構成変数で初期化されます。 さらに、/ docker-entrypoint-initdb.dにある拡張子.sh、.sql、.sql.gzのファイルを実行します。 ファイルはアルファベット順に実行されます。 SQLダンプをそのディレクトリにマウントすることでmysqlサービスを簡単に作成し、提供されたデータを含むカスタムイメージを提供できます。 SQLファイルは、デフォルトでMYSQL_DATABASE変数で指定されたデータベースにインポートされます。
大事なところ
コンテナが初めて起動されると、指定された名前の新しいデータベースが作成され、提供された構成変数で初期化されます。さらに、/ docker-entrypoint-initdb.dにある拡張子.sh、.sql、.sql.gzのファイルを実行します。
構成ファイル(必要部分のみ)
docker-compose.ymlの記述。以下ピンポイントのみ
docker-compose.ymlversion: '3' services: mysql: container_name: sample-mysql1 #作成されていると出来ないので新しく作成する場合ここの名前を変更 build: ./mysql/ #mysqlのDockerfileを使用してコンテナ volumes: - ./mysql/initdb.d:/docker-entrypoint-initdb.d # ./mysql/initdb.dは入れたいフォルダ名パス。 environment: MYSQL_DATABASE: mydb01 #はじめに作成します!データベース MYSQL_ROOT_PASSWORD: example # これでmysqlのrootユーザー exampleパスで入れる restart: alwaysmysql/initdb.d/Sample.sqlの中 Sample.sqlだけ書いているが複数あっても良い
Sample.sqlCREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, email VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, created DATETIME, modified DATETIME ); INSERT INTO users (email, password, created, modified) VALUES ('cakephp@example.com', 'secret', NOW(), NOW());
- 投稿日:2020-05-31T14:52:51+09:00
「Golang」 ×「Gorm」でシンプルに「Mysql」を操作する
「
REST API
サーバから受け取ったリクエストパラメータの内容を元にリレーショナルデータベース(Mysql
)を更新する」という流れで、説明を進めています。以下の記事の続編という形で投稿を行っておりますので、仕様などの前提条件はこちらで確認していただけるとありがたいです。
データベース(Mysql)準備
コードを実装する前に、
Mysql
上でデータベースの作成を行います。
※Mysql
自体導入していない場合は、インストールが必要です。詳細は他のサイトで解説されているのでここでは割愛します。# ルートユーザーでログイン mysql -uroot # mysql shell上 CREATE DATABASE { データベース名 }; # ログインユーザー作成 GRANT ALL PRIVILEGES ON { データベース名 }.* TO 'username'@'localhost' IDENTIFIED BY 'password'; # 一度mysqlからログアウトして、再度作成したユーザーでログイン mysql -u username -p # 念の為、データベースが作成されているか確認 SHOW DATABASES;コード実装
バージョン情報
- go 1.14
- github.com/jinzhu/gorm v1.9.12
- gopkg.in/ini.v1 v1.56.0
ORMマッピング
SQL
文でデータベースを操作することも可能ですが、今回は「コードを簡素化する」・「単純なDB操作のみ行う」ためにORM
でマッピングします。
データベースの複雑な操作が必要な場合はSQL
をそのまま書いたほうが、メンテナンスしやすいと思います。
Gorm
を採用した理由としては「スター数が多い」「ドキュメントが充実している」からです。root上でgoモジュールインストールgo get github.com/jinzhu/gormフォルダ構成
フォルダ構成merchandise_control_system ├── config │ └── config.go ├── controllers │ └── webserver.go ├── models │ └── middleware.go ├── config.ini ├── go.mod ├── go.sum └── main.goサーバポート情報・データベース接続情報をconfigに記載する
APIサーバのポート番号、DBの接続情報は一箇所にまとめ読み込むようにすることで可読性が向上します。
root上でgoモジュールインストールgo get gopkg.in/ini.v1config.ini[db] db_driver_name = mysql db_name = { データベース名 } db_user_name = { データベースユーザー名 } db_user_password = { データベースパスワード } db_host = 127.0.0.1 db_port = 3306 [api] server_port = 8080config/config.gopackage config import ( "gopkg.in/ini.v1" "log" "os" ) type ConfigList struct { DbDriverName string DbName string DbUserName string DbUserPassword string DbHost string DbPort string ServerPort int } var Config ConfigList func init() { cfg, err := ini.Load("config.ini") if err != nil { log.Printf("Failed to read file: %v", err) os.Exit(1) } Config = ConfigList{ DbDriverName: cfg.Section("db").Key("db_driver_name").String(), DbName: cfg.Section("db").Key("db_name").String(), DbUserName: cfg.Section("db").Key("db_user_name").String(), DbUserPassword: cfg.Section("db").Key("db_user_password").String(), DbHost: cfg.Section("db").Key("db_host").String(), DbPort: cfg.Section("db").Key("db_port").String(), ServerPort: cfg.Section("api").Key("server_port").MustInt(), } }コード全体
イメージとしては、
main.go
からコントローラを呼び出し、APIサーバを起動。
APIリクエストが行われると、コントローラ内からモデルが呼び出され、データベースの値を参照・更新。
最終的にレスポンスが返されるといった流れになります。main.gopackage main import ( "merchandise_control_system/controllers" ) func main() { controllers.StartWebServer() }controllers/webserver.gopackage controllers import ( "encoding/json" "fmt" "github.com/gorilla/mux" "io/ioutil" "log" "merchandise_control_system/config" "merchandise_control_system/models" "net/http" "strconv" ) type DeleteResponse struct { Id string `json:"id"` } func rootPage(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Welcome to the Go Api Server") fmt.Println("Root endpoint is hooked!") } func fetchAllItems(w http.ResponseWriter, r *http.Request) { var items []models.Item // modelの呼び出し models.GetAllItems(&items) responseBody, err := json.Marshal(items) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/json") w.Write(responseBody) } func fetchSingleItem(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] var item models.Item // modelの呼び出し models.GetSingleItem(&item, id) responseBody, err := json.Marshal(item) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/json") w.Write(responseBody) } func createItem(w http.ResponseWriter, r *http.Request) { reqBody, _ := ioutil.ReadAll(r.Body) var item models.Item if err := json.Unmarshal(reqBody, &item); err != nil { log.Fatal(err) } // modelの呼び出し models.InsertItem(&item) responseBody, err := json.Marshal(item) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/json") w.Write(responseBody) } func deleteItem(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] // modelの呼び出し models.DeleteItem(id) responseBody, err := json.Marshal(DeleteResponse{Id: id}) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/json") w.Write(responseBody) } func updateItem(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] reqBody, _ := ioutil.ReadAll(r.Body) var updateItem models.Item if err := json.Unmarshal(reqBody, &updateItem); err != nil { log.Fatal(err) } // modelの呼び出し models.UpdateItem(&updateItem, id) convertUintId, _ := strconv.ParseUint(id, 10, 64) updateItem.Model.ID = uint(convertUintId) responseBody, err := json.Marshal(updateItem) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/json") w.Write(responseBody) } func StartWebServer() error { fmt.Println("Rest API with Mux Routers") router := mux.NewRouter().StrictSlash(true) router.HandleFunc("/", rootPage) router.HandleFunc("/items", fetchAllItems).Methods("GET") router.HandleFunc("/item/{id}", fetchSingleItem).Methods("GET") router.HandleFunc("/item", createItem).Methods("POST") router.HandleFunc("/item/{id}", deleteItem).Methods("DELETE") router.HandleFunc("/item/{id}", updateItem).Methods("PUT") return http.ListenAndServe(fmt.Sprintf(":%d", config.Config.ServerPort), router) }models/middleware.gopackage models import ( "fmt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" "log" "merchandise_control_system/config" "time" ) type Model struct { ID uint `gorm:"primary_key" json:"id"` CreatedAt *time.Time `json:"created_at"` UpdatedAt *time.Time `json:"updated_at"` DeletedAt *time.Time `json:"deleted_at"` } type Item struct { Model JanCode string `gorm:"size:255" json:"jan_code,omitempty"` ItemName string `gorm:"size:255" json:"item_name,omitempty"` Price int `json:"price,omitempty"` CategoryId int `json:"category_id,omitempty"` SeriesId int `json:"series_id,omitempty"` Stock int `json:"stock,omitempty"` Discontinued bool `json:"discontinued"` ReleaseDate *time.Time `json:"release_date,omitempty"` } var Db *gorm.DB func GetAllItems(items *[]Item) { Db.Find(&items) } func GetSingleItem(item *Item, key string) { Db.First(&item, key) } func InsertItem(item *Item) { Db.NewRecord(item) Db.Create(&item) } func DeleteItem(key string) { Db.Where("id = ?", key).Delete(&Item{}) } func UpdateItem(item *Item, key string) { Db.Model(&item).Where("id = ?", key).Updates( map[string]interface{}{ "jan_code": item.JanCode, "item_name": item.ItemName, "price": item.Price, "category_id": item.CategoryId, "series_id": item.SeriesId, "stock": item.Stock, "discontinued": item.Discontinued, "release_date": item.ReleaseDate, }) } // データベースの初期化 func init() { var err error dbConnectInfo := fmt.Sprintf( `%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=True&loc=Local`, config.Config.DbUserName, config.Config.DbUserPassword, config.Config.DbHost, config.Config.DbPort, config.Config.DbName, ) // configから読み込んだ情報を元に、データベースに接続します Db, err = gorm.Open(config.Config.DbDriverName, dbConnectInfo) if err != nil { log.Fatalln(err) } else { fmt.Println("Successfully connect database..") } // 接続したデータベースにitemsテーブルを作成します Db.Set("gorm:table_options", "ENGINE = InnoDB").AutoMigrate(&Item{}) if err != nil { fmt.Println(err.Error()) } else { fmt.Println("Successfully created table..") } }デモ
APIサーバを起動します。と同時にデータベース接続、テーブル作成が行われます。
go run main.goPostmanからリクエストを送ってみます。(curlコマンドでもOKです)。
【POST】 /item
最初はデータベースが空のため、データを作成します。
リクエストパラメータ{ "jan_code": "32739028488888", "item_name": "item_1", "price": 1000, "category_id": 1, "series_id": 1, "stock": 1000, "discontinued": true, "release_date": "2020-05-31T07:00:00.660666+09:00" }レスポンスパラメータ{ "id": 1, "created_at": "2020-05-31T13:46:09.932124+09:00", "updated_at": "2020-05-31T13:46:09.932124+09:00", "deleted_at": null, "jan_code": "32739028488888", "item_name": "item_1", "price": 1000, "category_id": 1, "series_id": 1, "stock": 1000, "discontinued": true, "release_date": "2020-05-31T07:00:00.660666+09:00" }DB(Mysql)select * from items; +----+---------------------+---------------------+------------+----------------+-----------+-------+-------------+-----------+-------+--------------+---------------------+ | id | created_at | updated_at | deleted_at | jan_code | item_name | price | category_id | series_id | stock | discontinued | release_date | +----+---------------------+---------------------+------------+----------------+-----------+-------+-------------+-----------+-------+--------------+---------------------+ | 1 | 2020-05-31 13:46:10 | 2020-05-31 13:46:10 | NULL | 32739028488888 | item_1 | 1000 | 1 | 1 | 1000 | 1 | 2020-05-31 07:00:01 | +----+---------------------+---------------------+------------+----------------+-----------+-------+-------------+-----------+-------+--------------+---------------------+ 1 row in set (0.00 sec)【GET】 /item/1
レスポンスパラメータ{ "id": 1, "created_at": "2020-05-31T13:46:10+09:00", "updated_at": "2020-05-31T13:46:10+09:00", "deleted_at": null, "jan_code": "32739028488888", "item_name": "item_1", "price": 1000, "category_id": 1, "series_id": 1, "stock": 1000, "discontinued": true, "release_date": "2020-05-31T07:00:01+09:00" }【GET】 /items
レスポンスパラメータ[ { "id": 1, "created_at": "2020-05-31T13:46:10+09:00", "updated_at": "2020-05-31T13:46:10+09:00", "deleted_at": null, "jan_code": "32739028488888", "item_name": "item_1", "price": 1000, "category_id": 1, "series_id": 1, "stock": 1000, "discontinued": true, "release_date": "2020-05-31T07:00:01+09:00" } ]【PUT】 /item/1
リクエストパラメータ{ "jan_code": "3273902878656", "item_name": "item_1_update", "price": 12000, "category_id": 1, "series_id": 1, "stock": 10, "discontinued": false, "release_date": "2020-05-30T10:30:19.978603+09:00" }レスポンスパラメータ{ "id": 1, "created_at": null, "updated_at": "2020-05-31T14:26:04.165559+09:00", "deleted_at": null, "jan_code": "3273902878656", "item_name": "item_1_update", "price": 12000, "category_id": 1, "series_id": 1, "stock": 10, "discontinued": false, "release_date": "2020-05-30T10:30:19.978603+09:00" }DB(Mysql)select * from items; +----+---------------------+---------------------+------------+---------------+---------------+-------+-------------+-----------+-------+--------------+---------------------+ | id | created_at | updated_at | deleted_at | jan_code | item_name | price | category_id | series_id | stock | discontinued | release_date | +----+---------------------+---------------------+------------+---------------+---------------+-------+-------------+-----------+-------+--------------+---------------------+ | 1 | 2020-05-31 14:25:15 | 2020-05-31 14:26:04 | NULL | 3273902878656 | item_1_update | 12000 | 1 | 1 | 10 | 0 | 2020-05-30 10:30:20 | +----+---------------------+---------------------+------------+---------------+---------------+-------+-------------+-----------+-------+--------------+---------------------+ 1 row in set (0.00 sec)【DELETE】 /item/1
レスポンスパラメータ{ "id": "1" }まとめ
Gorm
を使うと、比較的簡単にデータベース接続、テーブル作成、テーブル操作を行うことができました。
また、ORM
の特徴として、DBを他のDB(例えばPostgreSQL
)に変更したとしてもコードの変更が少なくて済むのもメリットかと思います。細かいコードメンテナンスは必要ですが、一旦最低限の「APIサーバ起動」と「DB接続」が可能になりました。
今後こちらのサーバサイドコードを成長させながら、「ビュー」部分をReactNative
で実装していきたいと思います。
- 投稿日:2020-05-31T09:40:11+09:00
さくらVPSでLAMP + Wordpress環境を構築する方法まとめ
さくらVPSでLAMP + Wordpress環境を構築する方法まとめ
学習用にさくらVPSでLAMP環境を構築したので、手順をまとめます.
目次
動作環境
OS : macOS Mojave 10.14.6
VPS OS : centOS
手順
さくらVPSの申し込み
さくらのwebサイト>VPS>2週間無料でお試し
にアクセス
サーバをカートに入れ申し込み.メールに記載されているIDとパスワードでログインし,VPSコントロールパネルにログイン
各種設定>OSインストール
*OSをインストールする際にVPSにログインするためのパスワードを入力するので忘れずにメモします.
これでさくらVPSの申し込みからOSのインストールまでが完了です.
ssh接続
つぎにローカルPCからインターネット上のVPSに接続するためのSSH接続の設定手順をまとめます.
1. Terminal起動とroot権限でログイン
手元のMACでTerminalを起動します.
そして以下のsshコマンドで接続します.
パスワードはOSをインストールした際に入力したものです.$ ssh root@VPSのIPアドレス
2. ソフトウエアのupdate
$ yum update
3. 一般ユーザの作成
$ adduser jun1 #user追加 $ passwd jun1 #password設定sudoが使えるように設定
$ visudo
wheel ALL=(ALL) ALL #コメントアウトを外すjun1ユーザをwheelグループに追加
$ usermod -aG wheel jun1 $ groups jun1 jun1 : jun1 wheeljun1でログインできるか確認
$ ssh jun1@VPSのIPアドレス $ パスワード入力4. ssh鍵認証の設定
ローカルのPCのターミナルを起動して実行
MAC$ ssh-keygen -t rsa -v MAC$ ls ~/.ssh config id_rsa id_rsa.pub known_hostssshでVPSに接続
VPS$ mkdir .ssh VPS$ chmod 700 .sshローカルPCからVPSへ公開鍵を転送
ローカルPCMAC$ scp ~/.ssh/id_rsa.pub jun1@VPSのIPアドレス:~/.ssh/authorized_keys MAC$ VPSのパスワード入力鍵を利用してサーバにログイン
ローカルPCMAC$ ssh -i ~/.ssh/id_rsa jun1@VPSのIPアドレスssh接続のセキュリティ設定
1.ポート番号の設定
VPS$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.ort #設定ファイルのバックアップ $ sudo vim /etc/ssh/sshd_configPortを検索し、#を消して, 22 -> 56789(任意の番号で可)
2.パスワード認証の無効化
PasswordAuthenticationを検索し、
noに変更3.rootログインの無効化
PermitRootLoginで検索し,noに変更
4.設定ファイルの確認
VPS$ sudo sshd -t #設定ファイルに構文ミスがないか確認.何も出なければOK $ sudo systemctl restart sshd #sshdの再起動5.ファイアウォールの設定
VPS$ sudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-56789.xml $ sudo vim /etc/firewalld/services/ssh-56789.xmlport番号を22 -> 56789に変更
VPS$ sudo firewall-cmd --reload >success $ sudo firewall-cmd --permanent --add-service=ssh-56789 >success $ sudo firewall-cmd --reload >success $ sudo firewall-cmd --list-all >ssh-567896.SSH動作確認
上記で開いていたターミナルを閉じずに別タブを開く
MAC$ ssh -p 56789 -i ~/.ssh/id_rsa jun1@VPSのIPアドレス7. sshをファイアウォールから削除
VPS$ sudo firewall-cmd --permanent --remove-service=ssh $ sudo firewall-cmd --reload最後に念の為、ssh接続できるか確認
MAC$ ssh -p 56789 -i ~/.ssh/id_rsa jun1@VPSのIPアドレスapacheのインストール
VPS$ sudo yum install httpdApacheを起動
VPS$ sudo systemctl start httpd $ systemctl status httpd #Activeと表示されているか確認Firewallの設定
VPS$ sudo firewall-cmd --add-service=http --zone=public --permanent $ sudo firewall-cmd --add-service=https --zone=public --permanent $ sudo systemctl restart firewalldさくらVPSのパケットフィルタの設定
さくらVPSのコントロールパネル>設定>パケットフィルタ>WEBを許可
ブラウザからApacheの動作確認
ブラウザにVPSのIPアドレスを入力し,以下のテストページが表示されればOK
Apacheの自動起動の設定
VPS$sudo systemctl enable httpd権限の設定
ドキュメントルートの所有権をapacheに変更します.
VPS$sudo groupadd web #グループの作成 $sudo usermod -aG web jun1 #グループにユーザの追加VPS$sudo chown apache:web /va/www/html/ $sudo chmod -R 775 /var/www/html/htmlファイルを作成しApacheの動作確認
VPS$ vim /var/www/html/index.html #適当に編集して保存ブラウザから開いて確認
ドメインの設定
ドメイン取得サイトから購入
今回はバリュードメインに会員登録し、購入します。
DNS設定
バリュードメインにログインし、DNSを設定
詳細は各ドメインサイトから確認します.バリュードメインの設定画面a VPSのIPアドレスブラウザにドメインを入力し、表示されるか確認
*DNSの反映には1日かかることもあります.リポジトリの設定
2つのリポジトリをインストールします.
epelリポジトリ(Linuxのリポジトリ)
remiリポジトリ(PHPのリポジトリ)epelリポジトリ
VPS$sudo yum repolist #epelリポジトリがない場合は以下実行 $sudo yum install epelremiリポジトリ
ブラウザからremiリポジトリのURLをコピー
VPS$sudo yum localinstall remiのurl
phpのインストール
インストールできるバージョンを確認
VPS$ yum list available | grep php-php71-common.x86_64を確認
VPS$ sudo yum --enablerepo=remi-php71 install php php-devel php-mysql php-gd php-mbstringApaceh再起動
VPS$ sudo systemctl restart httpdPHPの設定
VPS$ sudo cp /etc/php.ini /etc/php.ini.org #設定ファイルのバックアップ $ sudo vim /etc/php.iniファイルのアップロード上限を変更
php.inipost_max_size = 128M #8M -> 128M upload_max_filesize = 128M #2M -> 128MApaceh再起動
VPS$ sudo systemctl restart httpdPHPの動作確認
/var/www/html/index.php<?php echo 'Hello World';ブラウザにドメイン名を入力し,index.phpを確認する
mysqlのインストール
MariaDBの削除
VPS$ sudo yum remove mariadb-libs $ sudo rm -rf /var/lib/mysqlMySQLインストール
MySQL 5.7をインストールする
VPS$ sudo yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm $ sudo yum install mysql-community-serverMySQLの設定
VPS$ sudo systemctl start mysqld $ sudo cat /var/log/mysqld.log | grep 'temporary password' #初期接続パスワードを確認VPS$ mysql_secure_installation #以下、指示どおり設定していくVPS$ mysql -u root -p #ログインできるか確認文字コードをUTFに変更
VPS$ sudo vim /etc/my.confmy.confcharacter-set-server=utf8VPS$ sudo systemctl restart mysqld自動起動の設定
VPS$ sudo systemctl enable mysqldsslの設定
certbotを利用するためバーチャルホストを設定
VPS$ sudo vim /etc/httpd/conf.d/ドメイン名.confドメイン名.conf<VirtualHost *:80> DocumentRoot /var/www/html ServerName ドメイン名 </VirtualHost>certbotをインストール
certbotのwebサイトからソフトウエアとOSを選択
VPS$ sudo vim install certbot-apache証明書を取得
VPS$ sudo certbot --apache動作確認
ブラウザにドメイン名を入力し、httpsになっているか確認
wordpressのインストール
DBの準備
VPS$ mysql -u root -p mysql> create database myblog; mysql> create user 'myblog_user'@'localhost' identified with mysql_native_password by '任意のpassword' mysql> grant all privileges on myblog.* to 'myblog_user'@'localhost'; mysql> flush privileges;wordpressのダウンロード
VPS$ wget https://ja.wordpress.org/latest-ja.tar.gz $ sudo tart -zxvf latest-ja.tar.gz -C /var/www/ #圧縮ファイルを展開 $sudo chown -R apache:web wordpress/ $sudo vim /etc/httpd/conf/httpd.confhttpd.confDocumentRoot "/var/www/wordpress" <Directory "/var/www/wordpress">ドメイン名.confDocumentRoot /var/www/wordpressドメイン名-le-ssl.confDocumentRoot /var/www/wordpresswordpressの確認
終わりに
今回はさくらVPSにLAMP環境を構築する学習の内容をまとめました。
Linuxコマンドの勉強になりました。