20200218のMySQLに関する記事は5件です。

RailsアプリをMySQLで作成してherokuへデプロイする。

今回は初めからMySQLでRailsアプリを作成してherokuへデプロイする手順です。

こちらの記事を参考に進めました。
RailsDBをMySQLに変更してHerokuでデプロイまでする手順

ありがとうございました。ほぼこの通りにすれば完璧です。自分はデプロイするときにいくつか詰まったところがあったので記載していこうと思います。

MySQLでRailsアプリを作成

こちらの記事を参考にRailsアプリのDBをMySQLにします。

【Rails/MySQL】RailsにMySQLを導入する方法【プログラミング学習149日目】

多少詰まりますがエラーメッセージ見ながら進めればrails sできると思います。

上記記事の①から⑥まで進める。

③は割愛。④はheroku configで出てきます。入力ミスに気をつけてください。この通りに進めてできなければ他の記事を参考にしてください。(クレジットカードが登録されてないパターンもある)

デプロイ時

$ git push heroku master
~
error: unable to rewind rpc post data - try increasing http.postBuffer
error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54
fatal: the remote end hung up unexpectedly
Writing objects: 100% (8167/8167), 29.25 MiB | 54.00 KiB/s, done.
Total 8167 (delta 988), reused 0 (delta 0)
fatal: the remote end hung up unexpectedly
Everything up-to-date

調べたらgitのbufferが足りないということでした。容量を増やすか、既存のアプリを削除するかして突破できます。自分は他のアプリを削除しました。

デプロイ後

heroku run rake db:migrateheroku openできました!と思ったらエラー発生。logを見たら記事投稿時にエラーになってました。
ローカルのフォルダからpushするとcssが反映されないことがあるらしいです。
/config/environments/production.rb

config.assets.compile = true <=最初はfalseになってる

これで解決しました。

heroku openできました。お疲れ様でした。

参考

RailsDBをMySQLに変更してHerokuでデプロイまでする手順
【Rails/MySQL】RailsにMySQLを導入する方法【プログラミング学習149日目】

参考にさせていただきありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Flaskチュートリアル#3 ~ DB連携編 ~

前回までのあらすじと今回実装するもの

#1ではGETリクエストに対する処理を実装しました。
#2ではPOST, PUT, DELETEリクエストに対する処理を実装しました。
#3となる今回はこれまで実装した処理を全てDB連携した処理に書き換えていきます!

詳しくはこちらで紹介しています。

ソースコード

.env
DB_USER=root
DB_PASS=*********
init_db.py
import sqlalchemy
import os
from os.path import join, dirname
from dotenv import load_dotenv

load_dotenv(verbose=True)
dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)

DB_USER = os.environ.get('DB_USER')
DB_PASS = os.environ.get('DB_PASS')

url = f'mysql+mysqldb://{DB_USER}:{DB_PASS}@localhost/test?charset=utf8'

engine = sqlalchemy.create_engine(url, echo=True)

engine.execute(f'DROP TABLE IF EXISTS posts')

engine.execute('''
    CREATE TABLE posts (
        id INTEGER PRIMARY KEY AUTO_INCREMENT,
        title CHAR(30),
        body TEXT
    )
''')
db.py
import sqlalchemy
import os
from os.path import join, dirname
from dotenv import load_dotenv

load_dotenv(verbose=True)

dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)

DB_USER = os.environ.get("DB_USER")
DB_PASS = os.environ.get("DB_PASS")


url = f'mysql+mysqldb://{DB_USER}:{DB_PASS}@localhost/test?charset=utf8'

engine = sqlalchemy.create_engine(url, echo=True)
app.py
from flask import Flask, jsonify, request
from db import engine
import json

app = Flask(__name__)

db_data = [
    {'title': 'タイトル1', 'body': '本文1'},
    {'title': 'タイトル2', 'body': '本文2'},
    {'title': 'タイトル3', 'body': '本文3'},
    {'title': 'タイトル4', 'body': '本文4'},
    {'title': 'タイトル5', 'body': '本文5'},
]


app.config['JSON_AS_ASCII'] = False 

@app.route('/', methods=['GET'])
def index():
    return 'hello world'


@app.route('/posts', methods=['GET'])
def get_all_posts():
    if 'limit' in request.args:
        limit = request.args['limit']
        posts = engine.execute(f'''
            SELECT * FROM posts
            LIMIT {int(limit)}
        ''')
    else:
        posts = engine.execute(f'''
            SELECT * FROM posts
        ''')
    result = [dict(row) for row in posts]
    return jsonify(result)


@app.route('/post/<id>', methods=['GET'])
def get_post(id):
    posts = engine.execute(f'''
        SELECT * FROM posts
        WHERE id={int(id)}
    ''')
    result = [dict(row) for row in posts]
    return jsonify(result)


@app.route('/post/add', methods=['POST'])
def create_post():
    post = request.json
    engine.execute(f'''
        INSERT INTO posts (title, body)
        VALUES ('{post['title']}', '{post['body']}')
    ''')
    return 'success'


@app.route('/post/update/<id>', methods=['PUT'])
def update_post(id):
    post = request.json
    engine.execute(f'''
        UPDATE posts 
        SET title='{post['title']}', body='{post['body']}'
        WHERE id={int(id)}
    ''')
    return 'success'


@app.route('/post/delete/<id>', methods=['DELETE'])
def delete_post(id):
    engine.execute(f'''
        DELETE FROM posts
        WHERE id={int(id)}
    ''')
    return 'success'


if __name__ == '__main__':
    app.debug = True
    app.run()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

metabaseでのWHERE変数の組み方メモ

metabaseとは

OSSのWEBベースBIツールです。以下のQiitaが詳しい
https://qiita.com/acro5piano/items/0920550d297651b04387

特に気に入っているのがdockerでの利用が超かんたんな所。
適当なRDBと一緒にyamlを書いてcomposeを立ちあげれば、すぐに分析に使えます。

docker-composeのサンプル

なお、よくあるサンプルではmetabase.dbをvolume指定していないので、コンテナを再作成すると作った分析データが消えます。
Volume指定だいじ。

docker-compose.yml
version: '3'
services:
  metabase:
    image: metabase/metabase
    volumes:
      - ./metabase-data:/metabase-data
    environment:
      MB_DB_FILE: /metabase-data/metabase.db
    ports:
      - "3000:3000"
    links:
      - db
  db:
    image: mysql:5.6.26
    environment:
      MYSQL_ROOT_PASSWORD: ****
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: ***
      TZ: 'Asia/Tokyo'
    volumes:
      - ./db:/var/lib/mysql
      - ./mysql_conf:/etc/mysql/conf.d
    ports:
      - 3306:3306
volumes:
  db:
  metabase:

便利なSQLでの定義作成

metabaseはSQLでガシガシ条件を書いて、定義(分析)を公開することができるので、土方社内SEにもおすすめです。
ただし、使い込みの情報があまり国内になく、stackoverflowやgithubのissueからノウハウを拾って作らなければいけないケースが、結構あります。

詳しい使い方は以下の公式が詳しい。
https://www.metabase.com/docs/latest/users-guide/writing-sql.html

この文書では、この中に記載があるもの、無いものの中から使いたいケースがあったものを記載します。

変数

SQLで問い合わせを書いた場合に、変数が使える。
公式のヘルプもあるが、『こういう時どうすればいいんだ?』という事が結構記載がなかったりする。海外のフォーラムなどで解が得られたものをメモしていく。随時追記する。

2020-02-18:取り急ぎなんとかしたかったLIKEとINがわかったので、下書きから公開にします。

参考ページ

https://www.metabase.com/docs/latest/users-guide/13-sql-parameters.html

基本構文

metabaseの変数は基本的に以下のルールで構成される。
1. {} で囲むと変数になる。
- 変数は半角英数で命名する。
- フィルターラベルを指定すると入力枠に名称が表示される。
- 必須の制御は変数設定メニュー
- デフォルト値は事前に決めた固定しか登録できない
2. [[]]で囲むと、囲まれた範囲内の変数が入力されたときのみ、その中の構文が評価される。

デフォルト値の設定

参考:https://www.metabase.com/docs/latest/users-guide/13-sql-parameters.html

metabaseの変数設定エリアにも初期値を指定できるが、今日の日付などといった動的な値は設定できない。
metabaseの説明によれば、値を入力した時だけ、初期値がコメントアウトされるように記入すればよいとのこと。

WHERE createdAt = [[ {{dateOfCreation}} -- ]]CURRENT_DATE()

このSQLで記載し、該当の項目に何も入力しないと以下のクエリとして評価される。

WHERE createdAt = CURRENT_DATE()

何か入力するとこの様になる。

WHERE createdAt = '2020-02-01 00:00:00' -- CURRENT_DATE()

ちょっとHackっぽいが、結果が取れればよい。というスタンスのようだ

LIKE の書き方

LIKEで文字列を検索したい場合は以下のように記載するとよい。
ダブルクォーテーションでくくるとうまいことやっくれるようだ。

name LIKE "%"{{name}}"%"

また、比較対象の文字列に%を含めればよいのであれば、以下のような書き方でもOK
もちろんCONCAT以外でも各RDBの文字結合ができる書き方なら通る

name LIKE CONCAT('%',{{name}},'%')

IN の書き方

v0.25 から 数値タイプ のみIN句がNativeSupportされています。

/* 値タイプを数値にする */
id IN ({{id}})

それ以外の型はまだIssueがCloseされておらず、以下のような形での回避が提示されています。
https://github.com/metabase/metabase/issues/4728

/* mysql */
select count(*) from T
where find_in_set(day, {{day}}) <> 0;

/* postgresql */
select count(*) from T
where day = ANY (string_to_array({{day}},  ','));
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLの複数バージョンの衝突対処法

目的

MySQL8を入れた後に「初心者は8ではなく5.7を使った方がいい」という旨の記事を読み,後追いで5.7を入れたところ衝突が起きたのかmysql server.startなどをしても毎回エラーが起きるようになってしまった.
これを解決し,5.7をインストールしたい.

とにかくアンインストール

$ sudo rm -rf /usr/local/mysql
$ sudo rm -rf /Library/StartupItems/MYSQL
$ sudo rm -rf /Library/PreferencePanes/MySQL.prefPane
$ sudo rm -rf /Library/Receipts/mysql-.pkg
$ sudo rm -rf /usr/local/Cellar/mysql*
$ sudo rm -rf /usr/local/bin/mysql*
$ sudo rm -rf /usr/local/var/mysql*
$ sudo rm -rf /usr/local/etc/my.cnf
$ sudo rm -rf /usr/local/share/mysql*
$ sudo rm -rf /usr/local/opt/mysql*

とにかく消す.エラーを見ずに解決するなんて邪道だが,初心者のうちは成功体験を積むためにとにかく短時間で先に進むことを目的とする.

再びインストール

$ brew install mysql@5.7
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【docker】mysqlのコンテナがバグで立ち上がらなくなった

状況

dockerでmysqlのコンテナが全く起動できなくなってしまいました。

db            | 2020-02-18 11:55:23+09:00 [Note] [Entrypoint]: Entrypoint script for MySQ
db            | 2020-02-18 11:55:23+09:00 [Note] [Entrypoint]: Switching to dedicated use
db            | 2020-02-18 11:55:23+09:00 [Note] [Entrypoint]: Entrypoint script for MySQ
db            | 2020-02-18T02:55:23.964250Z 0 [Warning] TIMESTAMP with implicit DEFAULT verver option (see documentation for more details).
db            | 2020-02-18T02:55:23.970525Z 0 [Note] mysqld (mysqld 5.7.29) starting as p
db            | 2020-02-18T02:55:23.987944Z 0 [Note] InnoDB: PUNCH HOLE support available
db            | 2020-02-18T02:55:23.988018Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC
db            | 2020-02-18T02:55:23.988026Z 0 [Note] InnoDB: Uses event mutexes
db            | 2020-02-18T02:55:23.988030Z 0 [Note] InnoDB: GCC builtin __atomic_thread_
db            | 2020-02-18T02:55:23.988033Z 0 [Note] InnoDB: Compressed tables use zlib 1
db            | 2020-02-18T02:55:23.988037Z 0 [Note] InnoDB: Using Linux native AIO
db            | 2020-02-18T02:55:23.988249Z 0 [Note] InnoDB: Number of pools: 1
db            | 2020-02-18T02:55:23.988361Z 0 [Note] InnoDB: Using CPU crc32 instructions
db            | 2020-02-18T02:55:23.990183Z 0 [Note] InnoDB: Initializing buffer pool, to
db            | 2020-02-18T02:55:23.997519Z 0 [Note] InnoDB: Completed initialization of 
db            | 2020-02-18T02:55:23.999353Z 0 [Note] InnoDB: If the mysqld execution userhe man page of setpriority().
db            | 2020-02-18T02:55:24.090309Z 0 [ERROR] [FATAL] InnoDB: Table flags are 0 i
db            | 2020-02-18 11:55:24 0x7fb2e0664740  InnoDB: Assertion failure in thread 1
db            | InnoDB: We intentionally generate a memory trap.
db            | InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
db            | InnoDB: If you get repeated assertion failures or crashes, even
db            | InnoDB: immediately after the mysqld startup, there may be
db            | InnoDB: corruption in the InnoDB tablespace. Please refer to
db            | InnoDB: http://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.ht
db            | InnoDB: about forcing recovery.
db            | 02:55:24 UTC - mysqld got signal 6 ;
db            | This could be because you hit a bug. It is also possible that this binary
db            | or one of the libraries it was linked against is corrupt, improperly buil
db            | or misconfigured. This error can also be caused by malfunctioning hardwar
db            | Attempting to collect some information that could help diagnose the probl
db            | As this is a crash and something is definitely wrong, the information
db            | collection process might fail.
db            |
db            | key_buffer_size=8388608
db            | read_buffer_size=131072
db            | max_used_connections=0
db            | max_threads=151
db            | thread_count=0
db            | connection_count=0
db            | It is possible that mysqld could use up to
db            | key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 681
db            | /lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7fb2de9cf42a]
db            | mysqld(+0x699b25)[0x5562a20f0b25]
db            | mysqld(_ZN2ib5fatalD1Ev+0x12d)[0x5562a2b60d8d]
db            | mysqld(+0x11b68f1)[0x5562a2c0d8f1]
db            | mysqld(_Z6fil_ioRK9IORequestbRK9page_id_tRK11page_size_tmmPvS8_+0x2b0)[0x5562a2c17110]
db            | mysqld(_Z13buf_read_pageRK9page_id_tRK11page_size_t+0xce)[0x5562a2bcc33e]
db            | mysqld(_Z16buf_page_get_genRK9page_id_tRK11page_size_tmP11buf_block_tmPKcmP5mtr_tb+0x4aa)[0x5562a2b9b57a]
db            | mysqld(_Z31trx_rseg_get_n_undo_tablespacesPm+0x143)[0x5562a2b3f1f3]      
db            | mysqld(+0x698c99)[0x5562a20efc99]
db            | mysqld(_Z34innobase_start_or_create_for_mysqlv+0x2f3d)[0x5562a2b0c06d]   
db            | mysqld(_Z24ha_initialize_handlertonP13st_plugin_int+0x4f)[0x5562a216b0ff]
db            | mysqld(+0xb8c0f6)[0x5562a25e30f6]
db            | mysqld(_Z40plugin_register_builtin_and_init_core_sePiPPc+0x2f0)[0x5562a25e6300]
db            | mysqld(+0x6bbece)[0x5562a2112ece]
db            | mysqld(_Z11mysqld_mainiPPc+0xc71)[0x5562a2114a71]
db            | /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7fb2de9bb2e1]  
db            | mysqld(_start+0x2a)[0x5562a210aeaa]
db            | The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
db            | information that should help you find out what is causing the crash.

ログを見てみるとなにやら恐ろしげなことが書いてあります。

This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built or misconfigured. This error can also be caused by malfunctioning hardwar Attempting to collect some information that could help diagnose the problem As this is a crash and something is definitely wrong, the information collection process might fail.

どうやらmysqlのバグが原因のようです。なんらかの原因によりクラッシュしたみたいです。

何度、やり直してもこのエラーが出ます。
このコンテナを削除しまったく新しくmysqlのコンテナを作り直してもダメです。

とりあえず解決

こちらを参考に対処しました。
https://github.com/laradock/laradock/issues/1173

結局mysqlのイメージ、コンテナ、data volumeを削除してから再起動して解決しました。

イメージの削除

docker imagesで一覧を取得します。

$ docker images
REPOSITORY   TAG    IMAGE ID       CREATED
mysql        5.7    c4f186b9e038   2 weeks ago   435MB

コンテナを停止させてからdocker rmi (IMAGE ID)で削除します。

$ docker rmi c4f186b9e038

data volumeの削除

data volumeとしてマウントしているフォルダを削除します。docker-compose.ymlのvolumesで指定のファイルになります。

docker
 ├─mysql
 │  ├─conf.d
 │  └─data ←削除

立ち上げてみます

$ docker-compose up -d --build

自分はこれで無事起動することができました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む