20191101のMySQLに関する記事は12件です。

NULLが絡むIN/NOT IN の挙動 (MySQL)

MysqlのNOT IN句はNULLが絡むと初見ではちょっと気付けない挙動をします。MySQL以外でどうなのかは知りませんが。

以下のような見やすいテーブルの話をします。

id num name
1 1 hello
2 2 world
3 NULL !

まずは以下のクエリと実行結果を御覧ください。

SELECT * FROM `mytable` WHERE `num` IN (1, 3);

id, num, name
1, 1, hello

はい、特に不審な点はありませんね。
では次。

NULLの霊圧が…消えた…?

SELECT * FROM `mytable` WHERE `num` NOT IN (1, 3);

id, num, name
2, 2, world
SELECT * FROM `mytable` WHERE `num` IN (1, 3, NULL);

id, num, name
1, 1, hello

どうやら値がNULLだとINにもNOT INにも引っかからなくなるようです。:thinking:
ちなみに IN ('')NOT IN ('')でもNULLは引っかからない。

そして誰もいなくなった

SELECT * FROM `mytable` WHERE `num` NOT IN (1, 3, NULL);

id, num, name

0件。

分かった、条件にNULLを含めなければ良いんだな

…と思うじゃん?
油断すると簡単に以下のようなクエリになったりします。

SELECT * FROM `another_table` WHERE `another_table`.`id` NOT IN( 
    SELECT `num` FROM `mytable` 
);

この場合サブクエリ部分が(1, 2, NULL) となって1行も返ってこない悲しい結果になります。

回避方法

サブクエリ内でWHERE に IS NOT NULL を追加するなどしましょう。

SELECT * FROM `another_table` WHERE `another_table`.`id` NOT IN(
    SELECT num FROM `mytable` WHERE `num` IS NOT NULL
);
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLが死んだらやること Can't connect to local MySQL server through socket '/tmp/mysql.sock'

MySQLが
Can't connect to local MySQL server through socket '/tmp/mysql.sock'
だの
ERROR! The server quit without updating PID file
だの言われたときにやること。

macOS 10.14.5
MySQL

経緯

突然起動しなくなった。

$ mysql -u root -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

なんでや。

$ mysql.server restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL
.. ERROR! The server quit without updating PID file (/usr/local/var/mysql/****.local.pid).

ググってみても、だいたいみんな再インストールとか言うやん。

https://qiita.com/carotene4035/items/e00076fe3990b9178cc0

やってみる

$ sudo touch /tmp/mysql.sock

見事に
Can't connect to local MySQL server through socket '/tmp/mysql.sock'(38) #2だったのが38に
なりました。

$ sudo chown mysql:mysql /tmp

ダメでした。

やったこと

示されてるファイル ****.local.pid の確認

/usr/local/var/mysql/****.local.pid と言われているので、そのファイルを見に行く。(****は端末名)

$ ls /usr/local/var/mysql/

****.local.err はあるけど ****.local.pid はない。
この.errファイルを確認する。

****.local.err に記載のエラーログ確認

$ cat /usr/local/var/mysql/****.local.err

そうするとエラーの途中でサーバー起動できない理由みたいなのを言ってる。

 0 [ERROR] [MY-010270] [Server] Can't start server : Bind on unix socket: Address already in use
 0 [ERROR] [MY-010258] [Server] Do you already have another mysqld server running on socket: /tmp/mysql.sock ?

なんか他のプロセスが動いてるかもしれないって言われる。

プロセスの確認

$ ps aux | grep mysql

で確認してみるも、grep mysql つまりこのコマンド自体しかいないので、実際は他のプロセスが動いてなさそう。

/tmp/mysql.sock の移動

あちこちで言われている /tmp/mysql.sock がなんか悪さしてるようなので、取り除く。
いきなり削除してもいいんだけど、念のため

$ sudo mv /tmp/mysql.sock* ~

で別のところに退避。

tmp配下にmysql.sockがつくファイルがなくなったので、この状態で再度アクセスしてみる。

$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8

いぇーい!

結論

/tmp/mysql.sock をここから削除、または移動させる。

プログラムとmysqlの通信(unixソケット)を処理してくれるやつに、使っていないはずの接続設定が残ってしまっているので、取り除くことで新規に接続できるようになりました。

https://teratail.com/questions/121735

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

MySQL テーブルのid番号を1から連番にリセットする方法

MySQLのid番号 リセット方法

MySQLには初期設定でauto-increment機能が設定されています。
簡単にいうと連番機能です。
レコードを消しすとそのid番号が欠番となったまま、連番されてしまうため、id番号を1から振りなおす方法をご紹介いたします。

方法のみ知りたい方は以下のリンクをクリック

方法へジャンプ

状況:

たとえばこんな感じのテーブルがあり、id番号が順番に振られています。

id name
1 ANA
2 DELTA
3 JAL
4 UNITED
5 VANILA
6 PEACH

しかし、いくつかレコード削除などによって欠番が生じると下のような順番になります。

id name
1 ANA
3 JAL
4 UNITED
6 PEACH

上の状態でさらにレコードが追加となると下のような連番となります

7 Sky Mark  
8 Jet star

歯抜になってしまったid:2と5は新たにレコードを足しても最後のレコードのidから連番となるため、欠番となったままになってしまいます。

静的なテーブルでidが正しい連番でなければいけなかったため、このid番号を1から振り直す方法がないものか探した結果、なんとかできる方法に行き着いたのでご紹介します。

方法

ターミナル上で
1.mysqlに入る
mysql -u root -p
パスワードは基本的には空のままEnterでOK
2.データベースを選択
mysql> use データベース名
3.テーブルのidを定義し直す
mysql> set @n:=0;
mysql> update`テーブル名` set id=@n:=@n+1;
4.確認
mysql> select*from テーブル名;

以上の操作でidの番号を振り直すことができたはずです。

基本的にはレコードが入っているテーブルにて以上方法で連番しなおしてみてください。静的なテーブルでは以上の方法でOKです。

がしかし、

レコードが追加されるようなテーブルでは、次のid番号は最後に入っていたレコードの次の番号からになってしまうため、auto_increment自体をリセットする必要があります。

でも大丈夫

そんな時は以下の状況に応じた2つの方法をいずれか試してみてください。

1.レコードがすべて空の状態から

レコードが空であれば、

ALTER TABLE `テーブル名` auto_increment = 1;

でOK

2.レコードの途中から

本記事上部の連番リセット方法でレコード番号を振り直しをしたあとで。。。。
mysql> select*from テーブル名;
でid番号を振り直したテーブルを確認し、例えば下のテーブルなら

id name
1 ANA
2 JAL
3 UNITED
4 PEACH

次は5番から連番になるようにしたい!

ALTER TABLE `テーブル名` auto_increment = 開始したいid番号;
つまり
ALTER TABLE `テーブル名` auto_increment = 5;

でOK。次に入るレコードは5からの連番になります。

****************************************
プログラミング初級者が自身の備忘録も兼ねた記事ですのでなにか同様の問題でお困りの方にお役に立てたら嬉しいです。

テーブルのリレーションによっては本記事の番号振り直し自体がエラーになる場合がありますので、テーブル同士のリレーションおよび関係性を確認して記述の修正等適宜行い、実行してください。

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

MySQL かんたんにテーブルのid番号を1からリセットする方法

MySQLのid番号 リセット方法

MySQLには初期設定でauto-increment機能が設定されています。
簡単にいうと「自動連番機能」です。

ただ番号間にあるレコードを消すとそのid番号のみが欠番となったまま、無視され、最後の番号から連番されてしまうため、テーブル管理において不都合なことが生じる場合があります。

そこで本記事では

「id番号を1から振りなおす方法」をご紹介いたします。

方法のみ知りたい方は以下のリンクをクリック

方法へジャンプ

状況:

たとえばこんな感じのテーブルがあり、id番号が順番に振られています。

id name
1 ANA
2 DELTA
3 JAL
4 UNITED
5 VANILA
6 PEACH

しかし、いくつかレコード削除などによって欠番が生じると下のような順番になります。

id name
1 ANA
3 JAL
4 UNITED
6 PEACH

上の状態でさらにレコードが追加となると下のような連番となります

7 Sky Mark  
8 Jet star

歯抜になってしまったid:2と5は欠番となったまま。

静的なテーブルでこのid番号を1から振り直す方法がないものか探した結果、なんとかできる方法に行き着いたのでご紹介します。

方法

ターミナル上で
1.mysqlに入る
mysql -u root -p
パスワードは基本的には空のままEnterでOK
2.データベースを選択
mysql> use データベース名
3.テーブルのidを定義し直す
mysql> set @n:=0;
mysql> update`テーブル名` set id=@n:=@n+1;
4.確認
mysql> select*from テーブル名;

以上の操作でidの番号を振り直すことができたはずです。

基本的にはレコードが入っているテーブルにて以上の方法を試してみてください。
静的なテーブルでは基本的に以上の方法でOKです。

がしかし、

レコードが追加されるようなテーブルでは、上記リセットをかけても次のid番号は、もともと最後に入っていたレコードの次の番号からになってしまうため、mysqlのauto_increment自体をリセットする必要があります。

方法2

そんな時は以下の2つの方法を状況に応じて試してみてください。

1.レコードがすべて空の状態からリセットしたい

レコードが空であれば、

ALTER TABLE `テーブル名` auto_increment = 1;

でOK

2.レコードが複数存在する状態で最後のidの次から連番にしたい

本記事上部の連番リセット方法でレコード番号を振り直しをしたあとで。。。。
mysql> select*from テーブル名;
でid番号を振り直したテーブルを確認し、例えば下のテーブルなら

id name
1 ANA
2 JAL
3 UNITED
4 PEACH

次は5番から連番になるようにしたい!

ALTER TABLE `テーブル名` auto_increment = 開始したいid番号;
つまり
ALTER TABLE `テーブル名` auto_increment = 5;

でOK。次に入るレコードは5からの連番になります。

****************************************
プログラミング初級者が自身の備忘録も兼ねて書いた記事ですのでご指摘等ありましたら気軽にコメントください。なにか同様の問題でお困りの方にお役に立てたら嬉しいです。

テーブルのリレーションによっては本記事の番号振り直し自体がエラーになる場合がありますので、テーブル同士のリレーションおよび関係性を確認して記述の修正、一時コメントアウト等適宜行い、実行してください。

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

テーブルのid番号を1から連番にリセットする方法

MySQLのid番号 リセット方法

MySQLには初期設定でauto-increment機能が設定されています。
簡単にいうと連番機能です。
レコードを消したりして欠番となったまま、id番号の欠番状態を直す方法をご紹介いたします。

方法のみ知りたい方は以下のリンクをクリック

方法へジャンプ

こんなとき(id変更したい時の例)

たとえばこんな感じのテーブルがあり、id番号が順番に振られています。

id name
1 ANA
2 DELTA
3 JAL
4 UNITED
5 VANILA
6 PEACH

しかし、いくつかレコード削除などによって欠番が生じると下のような順番になります。

id name
1 ANA
3 JAL
4 UNITED
6 PEACH
7 Sky Mark  
8 Jet star

歯抜になってしまったidはあらたにレコードを足しても最後のレコードのidから連番となるため、欠番となったままになってしまいます。このid番号を1から振り直す方法がないものか探した結果、なんとかできる方法に行き着いたのでご紹介します。

方法

ターミナル上で
1.mysqlに入る
mysql -u root -p
2.データベースを選択
mysql> use データベース名
3.テーブルのidを定義し直す
mysql> set @n:=0;
mysql> update`テーブル名` set id=@n:=@n+1;
4.確認
mysql> select*from テーブル名;

以上の操作でidの番号を振り直すことができたはずです。

基本的にはレコードが入っているテーブルにて以上方法で連番しなおしてみてください。次に入る、レコードは最後に入っていたレコードの次の番号からになってしまうため、auto_increment自体をリセットする場合は以下になります。

レコードをすべて空にした状態からauto_incrementをリセットする場合

ALTER TABLE `テーブル名` auto_increment = 1;

でOK。施行後入るレコードは1からの連番になります。

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

MySQL Workbechからコマンドラインでmysqlに接続する

概要

MySQL Worckbenchに登録されてる接続先に、ターミナルから簡単にmysqlコマンドで接続する方法です。

SQLのトランザクションを検証したかったのですが、
WorkbenchのGUIからの複数のトランザクションを開始して、対話的ににクエリ実行する方法が思いつかなかったので、コマンドで実行する必要がありました。
(もっといい方法があるかもしれないけど)

接続方法が、SSHの踏み台経由(Standard TCP/IP over SSH)でも問題なく接続できました。

手順

起動後のトップ画面で、任意の接続先で右クリック→「Start Command Line Client」

スクリーンショット 2019-11-01 12.27.41.png

やったー!

スクリーンショット 2019-11-01 12.31.58.png

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

LaravelでMySQLのテーブルロックを実行する

実装例

占有ロック

 DB::raw('LOCK TABLES lock_target_table WRITE');

共有ロック

 DB::raw('LOCK TABLES lock_target_table READ');

Eloquentのクエリビルダを使う方法は見つけられなかったので、生クエリを実行している

ダメな例

HogeHogeModel::lockForUpdate()->get();

全レコードに対してlockForUpdate()しても、テーブルロックの挙動にならなかった。
(別のトランザクションから、まだ存在しないレコードに対して占有ロック(ギャップロック )をかけることができてしまい、その後デッドロックになるリスクがある)

検証

全行ロックだと存在しない行のロックがブロックされない例

T1 T2 コメント
BEGIN;
BEGIN;
SELECT * FROM locks FOR UPDATE; 行全部ロック
SELECT * FROM locks WHERE name="not_exist_record" FOR UPDATE; 存在しない行のロックが取れてしまう
>Empty set

テーブルロックで存在しない行のロックがうまくブロックされる例

T1 T2 コメント
BEGIN;
BEGIN;
LOCK TABLES locks WRITE; テーブルロック
SELECT * FROM locks WHERE name="not_exist_record" FOR UPDATE; 存在しない行のロック
... T1のテーブルロックが終わるまで待つ
COMMIT;
>Empty set T1のテーブルロックが終わったので実行される

Versions

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

pythonのMySQLdbで日本語の入ったクエリを投げる際のUnicodeEncodeError回避

概要

pythonからMySQLへとinsert文を投げたい時があります。
MySQLdbパッケージを使ってクエリを投げる際に、クエリに日本語が入っているとUnicodeEncodeErrorが出てしまいます。
これはMySQLdb.connect()の引数に"use_unicode=True"、"charset="utf8""というオプションを追加すると回避できるようです。

状況

こういったMySQLのデータベースがあるとします。

mysql> desc test;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| test_id   | int(11)     | NO   | PRI | NULL    |       |
| test_text | varchar(64) | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+

pythonからtest_textというカラムに文字列を追加したいという気持ちが生まれました。
普通にMySQLdbパッケージを使ってinsert文を投げてみます。

mysqltest.py
import MySQLdb

try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password
    )

    cur = conn.cursor()

    query = "insert into test values('1','aaa')"

    cur.execute(query)

except:
    cur.close()
    conn.close()

cur.close()
conn.commit()
conn.close()

アルファベット文字列なら普通にできます。

mysql> select * from test;
+---------+-----------+
| test_id | test_text |
+---------+-----------+
|       1 | aaa       |
+---------+-----------+

しかしながら日本語の文字列だと…。

mysqltest.py
(省略)
    query = "insert into test values('2','あああ')"

    cur.execute(query)
(省略)
Traceback (most recent call last):
  File "mysqltest.py", line 30, in <module>
    conn.commit()
_mysql_exceptions.OperationalError: (2006, '')

といったエラーが出ます。
これはtry文での例外をキャッチした後にconn.commit()をしようとして出たエラーのようです。
このスタックトレースではよくわからんのでexcept文が実行されたタイミングでスタックトレースを出してみましょう。

mysqltest.py
import MySQLdb
import traceback

try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password
    )

    cur = conn.cursor()

    query = "insert into test values('2','あああ')"

    cur.execute(query)

except:
    cur.close()
    conn.close()
    print(traceback.format_exc()) 

cur.close()
conn.commit()
conn.close()

するとこのように出てきます。

Traceback (most recent call last):
  File "mysqltest.py", line 25, in <module>
    cur.execute(query)
  File "C:\path\to\anaconda\lib\site-packages\MySQLdb\cursors.py", line 248, in execute
    query = query.encode(db.encoding, 'surrogateescape')
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 29-31: ordinal not in range(256)

latin-1という文字コードでクエリがエンコードできないという怒られが発生しています。
どうやらMySQLdbパッケージはデフォルトでlatin-1を使ってエンコードするようです。どうして?

対策

こちらを参考にすると、MySQLdb.connect()の引数でエンコード方法を指定できるようです。
"use_unicode=True"と"charset="utf8""を引数に与えてやると、

mysqltest.py
import MySQLdb
import traceback

try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password,
    use_unicode=True,
    charset="utf8"
    )

    cur = conn.cursor()

    query = "insert into test values('2','あああ')"

    cur.execute(query)

except:
    cur.close()
    conn.close()
    print(traceback.format_exc()) 

cur.close()
conn.commit()
conn.close()

クエリが無事utf-8でエンコードされ、上手くいきました。

mysql> select * from test;
+---------+-----------+
| test_id | test_text |
+---------+-----------+
|       1 | aaa       |
|       2 | あああ    |
+---------+-----------+
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PythonのMySQLdbで日本語の入ったクエリを投げる際のUnicodeEncodeError回避

概要

PythonからMySQLへとinsert文を投げたい時があります。
MySQLdbパッケージを使ってクエリを投げる際に、クエリに日本語が入っているとUnicodeEncodeErrorが出てしまいます。
これはMySQLdb.connect()の引数に"use_unicode=True"、"charset="utf8""というオプションを追加すると回避できるようです。

状況

こういったMySQLのデータベースがあるとします。

mysql> desc test;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| test_id   | int(11)     | NO   | PRI | NULL    |       |
| test_text | varchar(64) | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+

Pythonからtest_textというカラムに文字列を追加したいという気持ちが生まれました。
普通にMySQLdbパッケージを使ってinsert文を投げてみます。

mysqltest.py
import MySQLdb

try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password
    )

    cur = conn.cursor()

    query = "insert into test values('1','aaa')"

    cur.execute(query)

except:
    cur.close()
    conn.close()

cur.close()
conn.commit()
conn.close()

アルファベット文字列なら普通にできます。

mysql> select * from test;
+---------+-----------+
| test_id | test_text |
+---------+-----------+
|       1 | aaa       |
+---------+-----------+

しかしながら日本語の文字列だと…。

mysqltest.py
(省略)
    query = "insert into test values('2','あああ')"

    cur.execute(query)
(省略)
Traceback (most recent call last):
  File "mysqltest.py", line 30, in <module>
    conn.commit()
_mysql_exceptions.OperationalError: (2006, '')

といったエラーが出ます。
これはtry文での例外をキャッチした後にconn.commit()をしようとして出たエラーのようです。
このスタックトレースではよくわからんのでexcept文が実行されたタイミングでスタックトレースを出してみましょう。

mysqltest.py
import MySQLdb
import traceback

try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password
    )

    cur = conn.cursor()

    query = "insert into test values('2','あああ')"

    cur.execute(query)

except:
    cur.close()
    conn.close()
    print(traceback.format_exc()) 

cur.close()
conn.commit()
conn.close()

するとこのように出てきます。

Traceback (most recent call last):
  File "mysqltest.py", line 25, in <module>
    cur.execute(query)
  File "C:\path\to\anaconda\lib\site-packages\MySQLdb\cursors.py", line 248, in execute
    query = query.encode(db.encoding, 'surrogateescape')
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 29-31: ordinal not in range(256)

latin-1という文字コードでクエリがエンコードできないという怒られが発生しています。
どうやらMySQLdbパッケージはデフォルトでlatin-1を使ってエンコードするようです。どうして?

対策

こちらを参考にすると、MySQLdb.connect()の引数でエンコード方法を指定できるようです。
"use_unicode=True"と"charset="utf8""を引数に与えてやると、

mysqltest.py
import MySQLdb
import traceback

try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password,
    use_unicode=True,
    charset="utf8"
    )

    cur = conn.cursor()

    query = "insert into test values('2','あああ')"

    cur.execute(query)

except:
    cur.close()
    conn.close()
    print(traceback.format_exc()) 

cur.close()
conn.commit()
conn.close()

クエリが無事utf-8でエンコードされ、上手くいきました。

mysql> select * from test;
+---------+-----------+
| test_id | test_text |
+---------+-----------+
|       1 | aaa       |
|       2 | あああ    |
+---------+-----------+
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【rails6】bundle installできない。ld: library not found for -limported_openssl

rails 6.0.0に対応したアプリを作成しようと環境構築していた際に、bundle installができなくなり、さらに既存アプリも(rails 5.2.3で作成)開けなくなりました。既存アプリを再度開けるようにするまでの過程を記録します。
この記事を書いている現在でもrails6での環境構築はできていません。

本トピック関連の環境

rails (6.0.0 / 5.2.3)
macOS Mojave ver.10.14.6
mysql@5.7 / mysql@5.6

エラーが発生した経緯

(エラーの詳細は『既存アプリを開けるようにするためにやったこと』の下に書いています。)
rails 6.0.0にてAction text等の新機能を試してみたいと思い、rails 6.0.0をインストールしました。
rbenvを使って、rubyのバージョンを2.6.4にアップデート → アプリ用のディレクトリ作成 → そのディレクトリの中で、rails 6.0.0インストール。
rails _6.0.0_ new -d mysql .
ここから詰まりに詰まった3日間が始まりました。

bundle install
これが全く通りません。
rails 6.0.0の新規アプリも…
rails 5.2.3の既存アプリも…

既存アプリを開けるようにするためにやったこと

(ここでいう既存アプリはrails 5.2.3で作成)
1. rails 6.0.0のアンインストール
2. Homebrewのアンインストールと再インストール
3. mysql@5.6mysql@5.7のアンインストール
4. mysql@5.6の再インストール

この4つです。

1. rails 6.0.0のアンインストール

$ cd            //ホームディレクトリに移動
$ gem list     //railsのバージョン確認のため
$ gem uninstall rails --version 6.0.0
$ gem install rails --version 5.2.3  //必要に応じて

インストール先が違えば、そのディレクトリ内でアンインストールしてください。

2. Homebrewのアンインストールと再インストール

必要がなければこの手順はスキップしてください。
mysqlのアンインストールだけでよければ、以下の記事を参考に。

コマンドは随時更新されているので、公式から直接コピーした方が良いと思います。
必要であれば、アンインストールする前に$ brew listで何をHomebrew経由でインストールしているのか確認。

▼アンインストール

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"

▼インストール

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

ここで一旦、mysql@5.6をインストールして、既存アプリでrails sできないかな、と試してみましたが、だめでした。

[1]エラー

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) もしくは (38)

ここで/tmp/mysql.sockを作成すると、[2]エラーのときに再度/tmp/mysql.sockを削除することになるらしいので作成しない方がいいようです。
mysqlのプロセスを確認します。(たぶん動いていないから[1]エラーが出る)

$ ps -ax | grep mysql

以下、試してみた。

$ mysql.server start
$ mysql.server restart

しかしエラー解決できず…

[2]エラー

ERROR! The server quit without updating PID file (/usr/local/var/mysql/XXXX.local.pid).

ここで/usr/local/var/mysqlの配下に(ユーザー名).local.pidを作成しても、なにかコマンドを打つと勝手に消えます。
負のループに入ります。

以下の記事を参照して、とりあえずは既存アプリを開けるようにしました。

3. mysql@5.6mysql@5.7のアンインストール

前述の手順にも載せていますが、

この記事を参考にしました。
私は前の手順でHomebrewごとアンインストールしていたので、以下の手順から…

▼ローカルのmysqlを削除してmysqlインストール

$ 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*

▼mysqlコマンド打てないことを確認

$ mysql -v
# mysql: command not found

4. mysql@5.6の再インストール

$ brew install mysql56
$ brew reinstall https://raw.githubusercontent.com/Homebrew/homebrew-core/f171f1c74/Formula/mysql@5.6.rb

▼ パスを通す & mysqlの自動更新設定

//パスを通す
$ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile 

//自動更新設定
$ mkdir ~/Library/LaunchAgents 
$ ln -sfv /usr/local/opt/mysql\@5.6/*.plist ~/Library/LaunchAgents

// mysql起動
$ /usr/local/opt/mysql@5.6/bin/mysql.server start 

上記コマンド打ったあとに再度、既存アプリを開くため$ rails s
mysqlを入れ直しているせいなのか、no database〜みたいなエラーが出ましたが
エラー文に解決策も載せてあったので、そのまま打ちました。

$ rails db:create
$ bin/rake db:migrate RAILS_ENV=development

やっとアプリが開けるようになりました。

あとはHomebrewのアンインストールで消えてしまったものを再度入れ直して、現状rails5でアプリ開発しています。
はやくrails6でアプリ作成できる環境を整えたい…

エラー詳細

▼ bundle installができなかったときのエラーは以下の通りです。

XXXX:sample_app XXXX$ bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
(gemのリスト)
Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
/Users/XXXX/.rbenv/versions/2.6.5/bin/ruby -I /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/2.6.0 -r ./siteconf20191019-30330-sj3h0.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/opt/mysql@5.6/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... no
checking for MYSQL_OPT_SSL_ENFORCE in mysql.h... no
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... yes
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/opt/mysql@5.6/lib
-----
creating Makefile

current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -limported_openssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2 for inspection.
Results logged to /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/mysql2-0.5.2/gem_make.out

An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2

mysql2のお家がないよ、と言われました。
Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

エラーの最後に指示があったので、その通りにコマンドを打ちました。

$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'

しかしながら、エラーは継続します。

Building native extensions. This could take a while...
ERROR:  Error installing mysql2:
ERROR: Failed to build gem native extension.

    current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
/Users/XXXX/.rbenv/versions/2.6.5/bin/ruby -I /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/2.6.0 -r ./siteconf20191019-38722-ow1bgt.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/opt/mysql@5.6/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... no
checking for MYSQL_OPT_SSL_ENFORCE in mysql.h... no
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... yes
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/opt/mysql@5.6/lib
-----
creating Makefile

current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -limported_openssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2 for inspection.
Results logged to /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/mysql2-0.5.2/gem_make.out

ネットで検索したところ
ld: library not found for -limported_openssl
類似したエラーが原因で、ここで引っかかっているという記事がありました。

このエラー解決法を実行する前に、opensslの有無を確認するためにも
再度インストールしてみました。

$ brew install openssl
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
futhark

Error: openssl 1.0.2s is already installed
To upgrade to 1.0.2t, run `brew upgrade openssl`

openssl 1.0.2sは、すでにあるよ!と言われてしまいました。
念の為、$ brew upgrade openssl

無事にアップデートできました。
アップデート詳細の最後の方にまた指示があったので、それに従いました。

If you need to have openssl first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile

For compilers to find openssl you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl/include"

指示にある3つのコマンドを打ちました。

$ echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile`
$ bundle config --local build.mysql2 --with-ldflags=-L/usr/local/opt/openssl/lib`
$ bundle config --local build.mysql2 --with-cppflagss=-I/usr/local/opt/openssl/include

2と3は合わせて

$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/' -- --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib

これでも大丈夫みたいです。
解決策として「このコマンド打てば通った!」という事例が多いように思いました。
でも私の場合は通りませんでした。
同様のエラーに遭う方もいるようで…

mysql@5.7を入れることでエラーが
ld: library not found for -lsslに変わったりもしましたが、結局エラー解決できず…
逆にこれが悪かったのかもしれない。

以上です。

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

【rails6】bundle installできない。Mysql@5.6/5.7とgem mysql2(0.5.2)に関するエラー

rails 6.0.0に対応したアプリを作成しようと環境構築していた際に、bundle installができなくなり、さらに既存アプリも(rails 5.2.3で作成)開けなくなりました。既存アプリを再度開けるようにするまでの過程を記録します。
この記事を書いている現在でもrails6での環境構築はできていません。

本トピック関連の環境

rails (6.0.0 / 5.2.3)
macOS Mojave ver.10.14.6
mysql@5.7 / mysql@5.6

エラーが発生した経緯

(エラーの詳細は『既存アプリを開けるようにするためにやったこと』の下に書いています。)
rails 6.0.0にてAction text等の新機能を試してみたいと思い、rails 6.0.0をインストールしました。
rbenvを使って、rubyのバージョンを2.6.4にアップデート → アプリ用のディレクトリ作成 → そのディレクトリの中で、rails 6.0.0インストール。
rails _6.0.0_ new -d mysql .
ここから詰まりに詰まった3日間が始まりました。

bundle install
これが全く通りません。
rails 6.0.0の新規アプリも…
rails 5.2.3の既存アプリも…

既存アプリを開けるようにするためにやったこと

(ここでいう既存アプリはrails 5.2.3で作成)
1. rails 6.0.0のアンインストール
2. Homebrewのアンインストールと再インストール
3. mysql@5.6mysql@5.7のアンインストール
4. mysql@5.6の再インストール

この4つです。

1. rails 6.0.0のアンインストール

$ cd            //ホームディレクトリに移動
$ gem list     //railsのバージョン確認のため
$ gem uninstall rails --version 6.0.0
$ gem install rails --version 5.2.3  //必要に応じて

インストール先が違えば、そのディレクトリ内でアンインストールしてください。

2. Homebrewのアンインストールと再インストール

必要がなければこの手順はスキップしてください。
mysqlのアンインストールだけでよければ、以下の記事を参考に。

コマンドは随時更新されているので、公式から直接コピーした方が良いと思います。
必要であれば、アンインストールする前に$ brew listで何をHomebrew経由でインストールしているのか確認。

▼アンインストール

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"

▼インストール

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

ここで一旦、mysql@5.6をインストールして、既存アプリでrails sできないかな、と試してみましたが、だめでした。

[1]エラー

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) もしくは (38)

ここで/tmp/mysql.sockを作成すると、[2]エラーのときに再度/tmp/mysql.sockを削除することになるらしいので作成しない方がいいようです。
mysqlのプロセスを確認します。(たぶん動いていないから[1]エラーが出る)

$ ps -ax | grep mysql

以下、試してみた。

$ mysql.server start
$ mysql.server restart

しかしエラー解決できず…

[2]エラー

ERROR! The server quit without updating PID file (/usr/local/var/mysql/XXXX.local.pid).

ここで/usr/local/var/mysqlの配下に(ユーザー名).local.pidを作成しても、なにかコマンドを打つと勝手に消えます。
負のループに入ります。

以下の記事を参照して、とりあえずは既存アプリを開けるようにしました。

3. mysql@5.6mysql@5.7のアンインストール

前述の手順にも載せていますが、

この記事を参考にしました。
私は前の手順でHomebrewごとアンインストールしていたので、以下の手順から…

▼ローカルのmysqlを削除してmysqlインストール

$ 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*

▼mysqlコマンド打てないことを確認

$ mysql -v
# mysql: command not found

4. mysql@5.6の再インストール

$ brew install mysql56
$ brew reinstall https://raw.githubusercontent.com/Homebrew/homebrew-core/f171f1c74/Formula/mysql@5.6.rb

▼ パスを通す & mysqlの自動更新設定

//パスを通す
$ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile 

//自動更新設定
$ mkdir ~/Library/LaunchAgents 
$ ln -sfv /usr/local/opt/mysql\@5.6/*.plist ~/Library/LaunchAgents

// mysql起動
$ /usr/local/opt/mysql@5.6/bin/mysql.server start 

上記コマンド打ったあとに再度、既存アプリを開くため$ rails s
mysqlを入れ直しているせいなのか、no database〜みたいなエラーが出ましたが
エラー文に解決策も載せてあったので、そのまま打ちました。

$ rails db:create
$ bin/rake db:migrate RAILS_ENV=development

やっとアプリが開けるようになりました。

あとはHomebrewのアンインストールで消えてしまったものを再度入れ直して、現状rails5でアプリ開発しています。
はやくrails6でアプリ作成できる環境を整えたい…

エラー詳細

▼ bundle installができなかったときのエラーは以下の通りです。

XXXX:sample_app XXXX$ bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
(gemのリスト)
Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
/Users/XXXX/.rbenv/versions/2.6.5/bin/ruby -I /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/2.6.0 -r ./siteconf20191019-30330-sj3h0.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/opt/mysql@5.6/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... no
checking for MYSQL_OPT_SSL_ENFORCE in mysql.h... no
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... yes
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/opt/mysql@5.6/lib
-----
creating Makefile

current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -limported_openssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2 for inspection.
Results logged to /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/mysql2-0.5.2/gem_make.out

An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2

mysql2のお家がないよ、と言われました。
Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

エラーの最後に指示があったので、その通りにコマンドを打ちました。

$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'

しかしながら、エラーは継続します。

Building native extensions. This could take a while...
ERROR:  Error installing mysql2:
ERROR: Failed to build gem native extension.

    current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
/Users/XXXX/.rbenv/versions/2.6.5/bin/ruby -I /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/2.6.0 -r ./siteconf20191019-38722-ow1bgt.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/opt/mysql@5.6/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... no
checking for MYSQL_OPT_SSL_ENFORCE in mysql.h... no
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... yes
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/opt/mysql@5.6/lib
-----
creating Makefile

current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -limported_openssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2 for inspection.
Results logged to /Users/XXXX/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/mysql2-0.5.2/gem_make.out

ネットで検索したところ
ld: library not found for -limported_openssl
類似したエラーが原因で、ここで引っかかっているという記事がありました。

このエラー解決法を実行する前に、opensslの有無を確認するためにも
再度インストールしてみました。

$ brew install openssl
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
futhark

Error: openssl 1.0.2s is already installed
To upgrade to 1.0.2t, run `brew upgrade openssl`

openssl 1.0.2sは、すでにあるよ!と言われてしまいました。
念の為、$ brew upgrade openssl

無事にアップデートできました。
アップデート詳細の最後の方にまた指示があったので、それに従いました。

If you need to have openssl first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile

For compilers to find openssl you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl/include"

指示にある3つのコマンドを打ちました。

$ echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile`
$ bundle config --local build.mysql2 --with-ldflags=-L/usr/local/opt/openssl/lib`
$ bundle config --local build.mysql2 --with-cppflagss=-I/usr/local/opt/openssl/include

2と3は合わせて

$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/' -- --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib

これでも大丈夫みたいです。
解決策として「このコマンド打てば通った!」という事例が多いように思いました。
でも私の場合は通りませんでした。
同様のエラーに遭う方もいるようで…

mysql@5.7を入れることでエラーが
ld: library not found for -lsslに変わったりもしましたが、結局エラー解決できず…
逆にこれが悪かったのかもしれない。

以上です。

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

Railsの便利機能「Application Template」で rails newと初期設定を自動化できた!

Railsアプリの新規作成から初期設定までをrails newrails db:createだけで完了させます。
rails newのあとにひたすらつづくgemのインストールや初期設定、めんどくさくないですか?
ちょっとしたtypoでRailsAbort! こういった人的ミスによるグツグツから開放されたくないですか?
テンプレートファイルは1つにまとめておけるので、Railsアプリ新規作成時の手順書としてもメンテできて一石二鳥ですよ!

環境

  • MacOS 10.14.6
  • Ruby 2.6.3
  • Rails 5.2.3
  • MySQL 8.0.16
  • Docker 19.03.4
  • docker-compose 1.24.1

※Dockerじゃなくてもイケます。

方法

RailsのApplication Templateという機能を使用します。

やること

  • ApplicationTemplateファイルをつくります。
  • rails new -m app_template.rb コマンドをうちます。
  • rails db:create コマンドをうちます。
  • 以上(*´∀`)

手順

①ApplicationTemplateファイルをつくる

プロジェクトフォルダのルートにapp_template.rbを新規作成します。

むずかしく考えなくていいです。
いつもやってる作業を上から順にかいていくだけです。

ちなみに、わたしのapp_template.rbはこんなかんじ。

docker-rails-mysql-template/app_template.rb at master · yukawahara0416/docker-rails-mysql-template

やってることは以下のとおり。

  • gemの指定
  • gem_groupの指定
  • コマンドの実行(bundle install, rspec:intallなど)
  • 不要なディレクトリの削除
  • 設定ファイルの取得
  • 設定ファイルの書き換え(日本語化、database.ymlなど)

もっと複雑なこともできるみたいですが、これだけでもかなり手間が省けます。

②rails new -mコマンドをうつ

いつものrails new-m app_template.rbをつけるだけです。

ルートフォルダに配置して使用する場合

$ rails new . -m app_template.rb

GitHubなど外部からテンプレファイルを取得する場合

$ rails new . -m https://raw.githubusercontent.com/yukawahara0416/docker-rails-mysql-template/master/app_template.rb

ほかのオプションと組み合わせて

$ rails new . -B -T -d mysql -m https://raw.githubusercontent.com/yukawahara0416/docker-rails-mysql-template/master/app_template.rb

-Bbundle installのスキップ、-TはMinitest用のtestディレクトリの生成スキップ、-d mysqlはDBをMySQLに指定しています。

ちなみに、Dockerならこんなかんじです。

$ docker-compose run web rails new . -B -T -d mysql -m https://raw.githubusercontent.com/yukawahara0416/docker-rails-mysql-template/master/app_template.rb

ターミナルはこんなかんじ。順番に実行してくれてますね。

       apply  https://raw.githubusercontent.com/yukawahara0416/docker-rails-mysql-template/master/app_template.rb
     gemfile    mysql2
     gemfile    rails-i18n
     gemfile    group :development, :test
      append    Gemfile
     gemfile    factory_bot_rails
     gemfile    guard-rspec
     gemfile    rspec-rails
     gemfile    rubocop
     gemfile    spring
     gemfile    spring-commands-rspec
      append    Gemfile
     gemfile    group :development
      append    Gemfile
     gemfile    better_errors
     gemfile    binding_of_caller
      append    Gemfile
     gemfile    group :test
      append    Gemfile
     gemfile    capybara
     gemfile    webdrivers (~> 3.0)
      append    Gemfile
         run    bundle install from "."
  ...中略...
      remove    test
      insert    app/views/layouts/application.html.erb
      remove    .gitignore
      create    .gitignore
      create    config/locales/ja.yml
      insert    config/application.rb
      insert    config/application.rb
      insert    config/environments/development.rb
    generate    rspec:install
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
      insert    .rspec
         run    guard init rspec from "."

③rails db:createコマンドをうつ

たった1コマンドでRailsアプリの初期設定までできてしまいました。
最後にDBを生成してYay!を確認してみましょう。

$ rails db:create

ずっとRailsの初期設定の自動化を夢見てきたので感激です(´;ω;`)

以上です。

参照

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