お疲れ様です。Ryujiです。
先日は数独の問題を作ったので、今日はそのデータをMysqlに保存します。
Python – Mysqlの接続の部分です。
今日はチームメンバーと一緒にデプロイのエラーをたくさん解決していました。
教えたり、教えられたり、人のコード見たり、人のエラーを見たり、すごく勉強になりますよね。
事前学習のおかげでカリキュラムの進捗が早かったので、教えるって機会が多かったのですが、教えているうちに自分が学んでいるってことが多いです。
Tech::Expertのキックオフでも講義がありましたが、教えるって最大のアウトプットだと思います。
これからも色々な人とコミュニケーションをとっていきたいと思います。
そして!ブログは!ピラミッドの最下部に隠された定着率100%のアウトプットだと信じています。
今日もやったことのアウトプット始めていきましょう。
Contents
今日やったこと
PythonでMysqlに接続しました。
まずは前提条件と事前準備です。
pythonでMysqlを扱うとき、2つの手法があるようです。
- mysqlclient
- mysql-connector-python
私はmysqlclientの方を選びました。それ前提で話を進めていきます。
事前準備
以下モジュールを導入します。
$ brew install mysql-connector-c $ mysql_config ###下記パスを確認するために実行 Usage: /usr/local/bin/mysql_config [OPTIONS] $ vi /usr/local/bin/mysql_config # Create options # libs="-L$pkglibdir" ### コメントアウト # libs="$libs -l " ### コメントアウト libs="-L$pkglibdir" ### 追記 libs="$libs -lmysqlclient -lssl -lcrypto" #追記
バグがあるようなので、vi /usr/local/bin/mysql_configを修正します。
$ pip install mysqlclient
導入完了。
侍エンジニアさんのブログがとてもわかりやすかったです。
https://www.sejuku.net/blog/82657
ソースコード
mysqlの接続部分はクラスとして用意しました。
探り探りやっていて、クラスにするのはベストプラクティスじゃないかもしれないですがご了承ください。
ConnectDB.py
・・・・・・・・
import MySQLdb
import os
import subprocess
class ConnectDB():
def __init__(self):
self.connection = MySQLdb.connect(
host='localhost',
user='root',
db='sudokunet_development')
self.cursor = self.connection.cursor()
def execute(self,sql_command):
print(sql_command)
self.cursor.execute(sql_command)
self.rows = self.cursor.fetchall()
self.connection.commit()
def get_data(self):
return self.rows
def display(self):
for row in self.rows:
print (row)
def close(self):
self.connection.close()
そして実行部分が次の部分です。
main.py
・・・・・・・・・・・・
from Sudoku import Sudoku as Sudoku
from Solve import Solve as Solve
from ConnectDB import ConnectDB as ConnectDB
import time
from datetime import *
・・・・数独部分・・・・
con = ConnectDB()
timestamp = datetime.now().strftime( '%Y-%m-%d %H:%M:%S' )
answer = ""
for item in ans.reshape(81).tolist():
answer += str(item)
question = ""
for item in ans.reshape(81).tolist():
question += str(item)
sql_command = 'INSERT INTO puzzles(answer,question,created_at,updated_at) values ("{answer}","{question}","{created_at}","{updated_at}")'.format(answer=answer,question=question,created_at=timestamp,updated_at=timestamp)
con.execute(sql_command)
con.display()
con.close()
まず実行部分のこれ
con = ConnectDB()
下のようにConnectDBってファイルから ConnectDBというモジュールをConnectDBって名前として、インポートしているのでConnectDB()で呼び出せます。
from ConnectDB import ConnectDB as ConnectDB
以下のように書くとdatetimeって標準ライブラリから全てのモジュールを、インポートするって命令になります。
from datetime import *
answerとquestionは[1,2,3,4,・・・5,6]って形になっていたので、一次元配列に変換して、文字列に直しました。
もっと効率的にかける方法があるはずです。
answer = ""
for item in ans.reshape(81).tolist():
answer += str(item)
question = ""
for item in ans.reshape(81).tolist():
question += str(item)
はい、次の部分が難しかったです。Tech::Expertのカリキュラムでも出てきましたが、割とすっ飛ばしてしまいました。
RailsではActive:Recordがうまいことやってくれますが、生のPythonは自力でSQL文をしなければなりません。わかりやすくてインデントしましたが、一行で書くのをお勧めします。
sql_command = 'INSERT INTO
puzzles(
answer,
question,
created_at,
updated_at
)
values (
"{answer}",
"{question}",
"{created_at}",
"{updated_at}")
'.format(
answer=answer,
question=question,
created_at=timestamp,
updated_at=timestamp
)
puzzlesテーブルにvalueがformat以下で記載したデータを追加するSQL文です。
このSQL文をConnectDBクラスのexecute関数に飛ばしています。
def execute(self,sql_command):
print(sql_command)
self.cursor.execute(sql_command) #sql文の実行
self.rows = self.cursor.fetchall() #データを取得し、rowsに保存
self.connection.commit() #DB変更内容を保存
つまづいたこと
Railsみたいにcreateメソッドやnewメソッドがあるかな!って思ってたらなかったです。そうですよね!Rubyもデフォルトだとないですもん。
pythonにも、Djangoってフレームワークがあるらしいので、それ使ったらRailsと同じ感覚で使えるかもしれません。
SQL文はないがしろにしまいがちですが、きちっと勉強しておいたほうがいいでしょう。
まとめ
今日はDB接続部分を実装しました。明日からはまたRubyの方へ戻って進めていきます。