20190524のMySQLに関する記事は3件です。

Heroku 本番環境 [Mysql2::Error::ConnectionError: Access denied for user root@localhost (using password: NO)] エラー

注)本ページに出てくる、usernameや、password、host値は存在しない値です。

問題:

rails c production で User.createをしようとしたら、
Mysql2::Error::ConnectionError: Access denied for user 'b2a63e570bc849'@'52.204.50.03' (using password: NO)
と言われてしまいました。

ターミナル
$ heroku config #mysql周辺情報をチェックします。
# 注意 'mysql2://[ユーザ名]:[パスワード]@[ホスト名]/[スキーマ名]?reconnect=true' です。

CLEARDB_DATABASE_URL:     mysql://kefbwfffn349:31w1dd54@us-cdbr-iron-east-04.cleardb.net/heroku_sufbd6sjdhsb5d?reconnect=true
DATABASE_PASSWORD:        31w1dd54
DATABASE_URL:             mysql2://kefbwfffn349:31w1dd54@us-cdbr-iron-east-04.cleardb.net/heroku_sufbd6sjdhsb5d?reconnect=true

$ mysql -u kefbwfffn349 -h us-cdbr-iron-east-04.cleardb.net -p  #mysqlに入れるか?
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 
...
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit # 入れました。

host,username,passwordはあってるのに、、、
となると,

検証

原因はエラー文の中のusing password: NOかな???と思い、

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  username: root
  password: 
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

production:
  <<: *default
  database: heroku_sufbd6sjdhsb5d
  username: kefbwfffn349
  host: us-cdbr-iron-east-04.cleardb.net
  password: <%= ENV['DATABASE_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock

password: <%= ENV['DATABASE_PASSWORD'] %>の部分を直接パスワードに置き換えることにしました。

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  username: root
  password: 
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

production:
  <<: *default
  database: heroku_sufbd6sjdhsb5d
  username: kefbwfffn349
  host: us-cdbr-iron-east-04.cleardb.net
  password: 31w1dd54
  socket: /var/lib/mysql/mysql.sock

そしたら、mysqlに繋がった、、、とりあえずは助かった、、、
本来なら、password: <%= ENV['DATABASE_PASSWORD'] %>でheroku:configのDATABASE_PASSWORD(キー)が読み込まれて、31w1dd54(値)が取得されるはずなのに、、、
色々調べてみます。

注)本ページに出てくる、usernameや、password、host値は存在しない値です。

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

Python + mysql-connector-python の使い方まとめ

最近、docker と python ばかり弄り回しているのですが、pythonの構文ってすごい気持ちいがいいですよね。

プログラム経験がそこまで高くないので、今までは、Typescriptが一番気持ちがいいプログラム言語だと思っていたのですが、Pythonの楽な構文と見通しの良さとipythonでその場で実行してプログラムを確認できる環境にとても幸せを感じています。笑

ちょっとMYSQLを触っていたので、mysqlとpythonを繋げるmysql-connector-pythonの使い方を忘れないようにするためのメモ書きです。

参考サイト
https://basicincome30.com/python3-mysql-connector

import mysql.connector

# コネクションの作成
conn = mysql.connector.connect(
    host='hostname',
    port='3306',
    user='username',
    password='password',
    database='dbname'
)

これだけで、mysqlと接続完了接続。楽!!!
dockerを使っているなら、hostnameは、mysqlの起動しているドッカーコンテナのコンテナ名にすればOK。

# コネクションが切れた時に再接続してくれるよう設定
conn.ping(reconnect=True)

# 接続できているかどうか確認
print(conn.is_connected())

mysqlは一定時間接続がないと止まるみたいなので、pingを送って接続が途切れないようにしておく。
接続確認も簡単。

テーブル作成

# DB操作用にカーソルを作成
cur = conn.cursor()

# id, name, priceを持つテーブルを(すでにあればいったん消してから)作成
table = 'test_table'
cur.execute("DROP TABLE IF EXISTS `%s`;", table)
cur.execute(
    """
    CREATE TABLE IF NOT EXISTS `%s` (
    `id` int auto_increment primary key,
    `name` varchar(50) not null,
    `price` int(11) not null
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
    """, table)
)

データ挿入(INSERT)

cur.execute("INSERT INTO test_table VALUES (1, 'BTC', 10200)")

# プレースホルダを利用して挿入
cur.execute("INSERT INTO test_table VALUES (2, 'ETH', %s)", (5000, ))
cur.execute("INSERT INTO test_table VALUES (%s, %s, %s)", (3 ,'XEM', 2500))
cur.execute("INSERT INTO test_table VALUES (%(id)s, %(name)s, %(price)s)", {'id': 4, 'name': 'XRP', 'price': 1000})

# executemanyで複数データを一度に挿入
records = [
  (5, 'MONA', 3000),
  (6, 'XP', 1000),
]
cur.executemany("INSERT INTO test_table VALUES (%s, %s, %s)", records)

データ選択 (SELECT)

cur.execute("SELECT * FROM test_table ORDER BY id ASC")

# 全てのデータを取得
rows = cur.fetchall()

for row in rows:
    print(row)

# 出力結果
"""
(1, 'BTC', 10200)
(2, 'ETH', 5000)
(3 ,'XEM', 2500)
(4, 'XRP', 1000)
(5, 'MONA', 3000)
(6, 'XP', 1000)
"""

# 1件取得
cur.execute("SELECT * FROM test_table WHERE name=%s", ('BTC', ))
print(cur.rowcount)
print(cur.fetchone())

# 出力結果
"""
1
(1, 'BTC', 10200)
"""

データ更新 (UPDATE)・データ削除 (DELETE)

# UPDATE
cur.execute('UPDATE test_table SET name=%s WHERE id=1', ('ビットコイン',))
cur.execute('UPDATE test_table SET name=%s WHERE id=%s', ('イーサリアム', 2))

# DELETE
cur.execute('DELETE FROM test_table WHERE id = 3')

コネクションを閉じる

# DB操作が終わったらカーソルとコネクションを閉じる
cur.close()
conn.close()

mysql-connector-pythonのいいところは、commitしないくてもデータベースに反映されるところがいいね。

今後はPythonメインでプログラムを書いていきたいから、徹底的に覚えていこう。

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

LaravelでMySQLへのデータ挿入時にエラーが出た場合の対処法

はじめに

LaravelのSeederでテストデータを入力しようとした際に、次のエラーが発生した。

SQLSTATE[HY000]: General error: 1364 Field 'カラム名' doesn't have a default value

NOT NULLであるフィールドにNULLをInsertした事によりエラーが出たようだ。
今回はこの警告を無効化することで対処する。

環境

  • Laravel 5.5.45
  • MySQL 5.7.26

対処法

config/database.phpstrictの値をfalseに設定する。

database.php
'mysql' => [
    // 略
    // 'strict' => true,
    'strict' => false,
    // 略
],

原因

stricttrueになっていると、次のようにsql_modeが設定される。

mysql> select @@GLOBAL.sql_mode;
 +---------------------------------------------------------------------------------------+
 | @@GLOBAL.sql_mode                                                                     |
 +---------------------------------------------------------------------------------------+
 | STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
 +---------------------------------------------------------------------------------------+
 1 row in set (0.00 sec)

sql_modeSTRICT_TRANS_TABLESが設定されていると、無効な値が挿入された場合にエラーを出すようになる。

参考

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