macOSにインストールしたMySQLWorkbench 8.0.23が起動しないときの対処法

macOSにインストールしたMySQLWorkbench 8.0.23が起動しない。

コマンドラインで実行すると以下のエラーメッセージが出力されていた。

❯ /Applications/MySQLWorkbench.app/Contents/MacOS/MySQLWorkbench
Fatal Python error: initfsencoding: unable to load the file system codec, sys.path = ['/Applications/MySQLWorkbench.app/Contents/Resources/libraries', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload']
ModuleNotFoundError: No module named 'encodings'

Current thread 0x0000000107ee8dc0 (most recent call first):
Abort trap: 6

エラーメッセージを見ると、Python3.7が見つからないようだ。

対処法は以下の通り。

(1)Python3.7をインストールする。

brew install python@3.7

(2)シンボリックリンクを作成する。

sudo ln -s /usr/local/Cellar/python@3.7/3.7.10_2/Frameworks/Python.framework /Library/Frameworks/Python.framework

以上で、MySQLWorkbenchが起動するようになった。

参考
* MySQL Bugs: #102364: MySQL Workbench 8.0.23 unable to start due to wrong system python paths
* python – How to add a path to the system path in MySQL Workbench for Mac (Big Sur) – Stack Overflow

LaravelのFormファサード(laravelcollective/html)でセレクトボックスを実装する

LaravelのFormファサード(laravelcollective/html)でセレクトボックスを実装する方法を解説する。

公式サイト

インストール

$ composer require laravelcollective/html

バージョンを指定してインストールすることもできる。

例:5.8をインストールする場合

$ composer require "laravelcollective/html":"5.8"

Form::select()の使い方

第1引数がselectタグのname属性、第2引数がoptionタグになる。

ソースコード

{{ Form::select(
    'pref', 
    [13=>'東京都',14=>'神奈川県', 26=>'京都府',27=>'大阪府']
) }}

実行結果

<select name="pref">
    <option value="13">東京都</option>
    <option value="14">神奈川県</option>
    <option value="26">京都府</option>
    <option value="27">大阪府</option>
</select>

第3引数は初期値になる。

ソースコード

{{ Form::select(
    'pref', 
    [13=>'東京都',14=>'神奈川県', 26=>'京都府',27=>'大阪府'], 
    26
) }}

実行結果

<select name="pref">
    <option value="13">東京都</option>
    <option value="14">神奈川県</option>
    <option value="26" selected="selected">京都府</option>
    <option value="27">大阪府</option>
</select>

第4引数はselectタグの属性になる。

ソースコード

{{ Form::select(
    'pref', 
    [13=>'東京都',14=>'神奈川県', 26=>'京都府',27=>'大阪府'], 
    null, 
    ['class'=>'form-control']
) }}

実行結果

<select class="form-control" name="pref">
    <option value="13">東京都</option>
    <option value="14">神奈川県</option>
    <option value="26">京都府</option>
    <option value="27">大阪府</option>
</select>

第4引数にplaceholderを指定すると、値のないoptionタグが要素の最初に作成される。

ソースコード

{{ Form::select(
    'pref', 
    [13=>'東京都',14=>'神奈川県', 26=>'京都府',27=>'大阪府'], 
    null, 
    ['class'=>'form-control', 'placeholder'=>'選択してください']
) }}

実行結果

<select class="form-control" name="pref">
<option selected="selected" value="">選択してください</option>
<option value="13">東京都</option>
<option value="14">神奈川県</option>
<option value="26">京都府</option>
<option value="27">大阪府</option>
</select>

第2引数を配列の入れ子にすると、選択肢が階層化される。

ソースコード

{{ Form::select('pref', [
    '関東地方'=>[13=>'東京都',14=>'神奈川県'],
    '近畿地方'=>[26=>'京都府',27=>'大阪府']
]) }}

実行結果

<select name="pref">
    <optgroup label="関東地方">
        <option value="13">東京都</option>
        <option value="14">神奈川県</option>
    </optgroup><optgroup label="近畿地方">
        <option value="26">京都府</option>
        <option value="27">大阪府</option>
    </optgroup>
</select>

Eloquentモデルを使う

pluck()メソッドを使うと、簡単に選択肢を作成できる。

$prefectures = Prefectures::query()
    ->orderBy('code)
    ->pluck('name', 'code');
return view('index')->with(['prefectures'=>$prefectures]);
{{ Form::select('pref', $prefectures) }}

SQLAlchemyを使ってMySQLに接続する

環境

$ cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)
$ python3 --version
Python 3.6.8

インストールする

$ pip install SQLAlchemy
$ pip install mysql-connector-python

確認する。

$ python3
Python 3.6.8 (default, Nov 16 2020, 16:55:22) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlalchemy
>>> sqlalchemy.__version__ 
'1.3.23'

使ってみる

#!python3
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import Column
from sqlalchemy.types import Integer, String

USER='...'
PASSWORD='...'
HOST='...'
DATABASE='...'

# MySQL Connector/Pythonを使うためmysqlconnectorを指定する
engine=create_engine(f'mysql+mysqlconnector://{USER}:{PASSWORD}@{HOST}/{DATABASE}')

# テーブルを定義する
Base=declarative_base()
class Animal(Base):
    __tablename__='animals'
    __table_args__=({"mysql_charset": "utf8mb4"})
    id=Column(Integer, primary_key=True, autoincrement=True)
    name=Column(String(30), nullable=False)

# テーブルを作成する
Base.metadata.create_all(engine)

# セッションを作成する
Session=sessionmaker(engine)
session=Session()

# データを追加する
cat=Animal(name='cat')
dog=Animal(name='dog')
session.add(cat)
session.add(dog)
session.commit()

# データを更新する
cat=session.query(Animal).get(1)
cat.name='pengin'
session.commit()

# データを取得する
animals=session.query(Animal).all()
for animal in animals:
    print('id=',animal.id,'name=',animal.name)

Python3からMySQLに接続する

MySQL Connector/Pythonの使い方を紹介する。

環境

$ cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)
$ python3 --version
Python 3.6.8

利用可能なMySQL Connector/Pythonoのバージョン

公式サイトのMySQL :: MySQL Connector/Python Developer Guide :: 3 Connector/Python Versionsを参照。

現行バージョンのMySQL Connector/Python 8.0は次のバージョンに対応している。

  • MySQL Server Versions
    • 8.0
    • 5.7
    • 5.6
    • 5.5
  • Python Versions
    • 3.9
    • 3.8
    • 3.7
    • 3.6
    • (2.7 and 3.5 before 8.0.24)

MySQL Connector/Pythonをインストールする

MySQL Connector/Python

pip install mysql-connector-python

MySQLに接続する

connect()コンストラクターは、MySQLサーバーへの接続を作成し、MySQLConnectionオブジェクトを返す。

import mysql.connector

USER='scott'
PASSWORD='password'
HOST='localhost'
DATABASE='employees'

cnx = mysql.connector.connect(
    user=USER,
    password=PASSWORD,
    host=HOST,
    database=DATABASE
)
cnx.close()

接続エラーを処理には、mysql.connector.Error例外をキャッチする。

import mysql.connector

USER='scott'
PASSWORD='password'
HOST='localhost'
DATABASE='employees'

try:
    cnx = mysql.connector.connect(
        user=USER,
        password=PASSWORD,
        host=HOST,
        database=DATABASE
    )
except mysql.connector.Error as err:
    print(err)
else:
    cnx.close()

テーブルを作成する

cursor()メソッドを使用して、カーソルオブジェクトを作成し、
カーソルオブジェクトのexecute()メソッドを使用してCREATE TABLE文を実行し、テーブルを作成する。

import mysql.connector

USER='scott'
PASSWORD='password'
HOST='localhost'
DATABASE='employees'

def create_table(cursor):
    SQL = (
        'CREATE TABLE IF NOT EXISTS animals ('
        '  id MEDIUMINT NOT NULL AUTO_INCREMENT,'
        '  name CHAR(30) NOT NULL,'
        '  PRIMARY KEY (id)'
        ');'
    )
    cursor.execute(SQL)

try:
    cnx = mysql.connector.connect(
        user=USER,
        password=PASSWORD,
        host=HOST,
        database=DATABASE,
    )
    cursor = cnx.cursor()
    create_table(cursor)
except mysql.connector.Error as err:
    print(err)
else:
    cnx.close()

データを追加する

カーソルオブジェクトのexecute()メソッドを使用してデータを登録し、
commit()メソッドを使用してコミットする。

失敗したときはrollback()メソッドを使用してロールバックする。

import mysql.connector

USER='scott'
PASSWORD='password'
HOST='localhost'
DATABASE='employees'

def create_table(cursor):
    SQL = (
        'CREATE TABLE IF NOT EXISTS animals ('
        '  id MEDIUMINT NOT NULL AUTO_INCREMENT,'
        '  name CHAR(30) NOT NULL,'
        '  PRIMARY KEY (id)'
        ');'
    )
    cursor.execute(SQL)

def insert(cursor):
    cursor.execute('INSERT INTO animals (name) VALUES (%s)', ('cat',))
    cursor.execute('INSERT INTO animals (name) VALUES (%(name)s)', {'name':'dog'})

try:
    cnx = mysql.connector.connect(
        user=USER,
        password=PASSWORD,
        host=HOST,
        database=DATABASE,
    )
    cursor = cnx.cursor()
    create_table(cursor)
    insert(cursor)
    cnx.commit()
    cursor.close()
except mysql.connector.Error as err:
    print(err)
else:
    cnx.close()

データを取得する

カーソルオブジェクトのexecute()メソッドを使用してSELECT文を実行する。

カーソルオブジェクトをイテレータとして使用し、結果セットの各行を取得する。

import mysql.connector

USER='scott'
PASSWORD='password'
HOST='localhost'
DATABASE='employees'

def select(cursor):
    cursor.execute('SELECT id,name FROM animals LIMIT %s', (3,))
    for (id, name) in cursor:
        print("id:{} name:{}".format(id, name))

try:
    cnx = mysql.connector.connect(
        user=USER,
        password=PASSWORD,
        host=HOST,
        database=DATABASE,
    )
    cursor = cnx.cursor()
    select(cursor)
    cursor.close()
except mysql.connector.Error as err:
    print(err)
else:
    cnx.close()