Python入門【DB(データベース)接続とDB操作の基本(MySQL編)】

python database

こんにちは、ミナトです。

「Pythonでデータベースを扱うにはどうすればいいの?」
「そもそもデータベースって何?」

というあなたのために今回はPythonでのDB操作の基本について解説します。今回は、アプリケーション開発でよく利用されるMySQLを例に解説をしていきます。

初心者にも分かりやすく解説していますので、安心して読み進めていただければと思います。

PythonでDBを操作するにはどうすればいいの?
アプリケーション開発では多くの場合、何かしらのデータベースにデータを保存します。
今回はPythonでデータベースを操作する方法について解説するな😆
以下のような方を対象としています
  • PythonでのDB操作について知りたい
  • PythonでのORMを利用する方法について知りたい
  • Pythonでプログラミングを学びたい初心者

DB(データベース)接続とDB操作の基本

データベースとは

データベースには様々な種類がありますが、ここでは代表的なデータベースであるリレーショナル・データベースについて説明します。本記事内では、「データベース = リレーショナル・データベース」と思ってください。

データベースは、エクセルのように表形式でデータを保存することができるミドルウェアです。

データベースを利用することでエクセルなどで管理するよりも大量のデータを効率的に管理できます。

また、SQLというクエリ言語を利用することで、データの追加、読み込み、更新、削除などが簡単に実行できます。

MacにMySQLをインストールする

Homebrewというパッケージマネージャを利用することで、Macに簡単にMySQLをインストールすることができます。Windowsをお使いの場合はお手数ですが、Googleで検索していただければと思います。

Homebrewのインストールを行っていない場合は、以下のページからHomebrewをインストールしておいてください。

Homebrewのインストール

Homebrewを利用してMySQLをインストールするには、以下のターミナルで以下のコマンドを実行してください。

インストールには時間がかかるので完了するまで少し待つようにしてください。

# MySQLのインストール
brew install mysql

MySQLを起動するには以下のコマンドを実行してください。

# 起動
brew services start mysql
# 停止
brew services start mysql

MySQLにアクセスするには、以下のコマンドを実行します。実行後、MySQLの対話型シェルが起動します。

mysql -u root

対話型シェルから抜けたい場合は、「exit;」を入力して「Enter」してください。

# 以下を入力して、Enter
mysql> exit;

Pythonでデータベースに接続する

MySQLに接続するためのパッケージには複数存在しますが、今回はmysql-connector-pythonを利用してMySQLに接続します。

mysql-connector-pythonをインストールするには、ターミナルで以下のコマンドを実行してください。

pip install mysql-connector-python

mysql-connector-pythonのインストールが完了したら、PythonからMySQLにアクセスします。

以下の例では、あなたのローカル端末のMySQLにアクセスし、SQLを実行し、「sample_db」という名前でデータベースを新規に作成しています。また、実行後はMySQLとの接続を切っています。

import mysql.connector

conn = mysql.connector.connect(host='127.0.0.1', user='root', password='')
cursor = conn.cursor()

cursor.execute(
    'CREATE DATABASE example_db'
)

cursor.close()
conn.close()

MySQLに接続し、データベースが作成されていることを確認してみましょう。

mysql> show databases;
--------------------------------------------------------------------
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| example_db          |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

データベースにデータを登録する

テーブの作成

まずはデータベースにテーブルを作成します。以下の例では、idとnameという列をもつusersテーブルを作成しています。

import mysql.connector

conn = mysql.connector.connect(host='127.0.0.1', user='root', password='', database='example_db')
cursor = conn.cursor()

cursor.execute(
    'CREATE TABLE users('
    'id int NOT NULL AUTO_INCREMENT,'
    'name varchar(20) NOT NULL,'
    'PRIMARY KEY(id))'
)

cursor.close()
conn.close()

ターミナルでMySQLにアクセスしてテーブルが作成されたことを確認します。

# 作成したDBに接続
mysql> use example_db; 

# 以下のように出力されたらOKです。
--------------------------------------------------------------------
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
--------------------------------------------------------------------

# テーブルの確認
mysql> show tables;
--------------------------------------------------------------------
+---------------------+
| Tables_in_sample_db |
+---------------------+
| users               |
+---------------------+
1 row in set (0.00 sec)
--------------------------------------------------------------------

# テーブル定義の確認
mysql> desc users;
--------------------------------------------------------------------
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
--------------------------------------------------------------------

データの登録

テーブルが作成できたので、INSERT文を利用してデータを登録します。

import mysql.connector

conn = mysql.connector.connect(host='127.0.0.1', user='root', password='', database='example_db')
cursor = conn.cursor()

cursor.execute('INSERT INTO users(name) values("Taro Yamada")')
conn.commit()

cursor.close()
conn.close()

データベースのデータを読み込む

SELECT文でデータを取得する場合は以下のように記述します。cursorをfor文で回すことで一行ずつデータが取得できます。

import mysql.connector

conn = mysql.connector.connect(host='127.0.0.1', user='root', password='', database='example_db')
cursor = conn.cursor()

cursor.execute('SELECT * FROM users')

for row in cursor:
    print(row)

cursor.close()
conn.close()

## 出力
(1, 'Taro Yamada')

データベースのデータを更新する

データを更新する場合は以下のようにUPDATE文を実行します。

import mysql.connector

conn = mysql.connector.connect(host='127.0.0.1', user='root', password='', database='example_db')
cursor = conn.cursor()

cursor.execute('UPDATE users set name = "Takeru Sato" WHERE id = 1')

cursor.execute('SELECT * FROM users')
for row in cursor:
    print(row)

cursor.close()
conn.close()

## 出力
(1, 'Takeru Sato')

データベースのデータを削除する

データを削除する場合は以下のようにDELETE文を実行します。

import mysql.connector

conn = mysql.connector.connect(host='127.0.0.1', user='root', password='', database='example_db')
cursor = conn.cursor()

cursor.execute('DELETE FROM users WHERE id = 1')

cursor.close()
conn.close()

SQLAlchemyを利用したデータの操作

SQLAlchemyとは

SQLAlchemyはORM(Object-relational mapping)といって、データベースのデータをPythonのオブジェクトを扱うように操作できるようにするもののことです。

ORMを利用する利点は、異なるDBの差異を吸収してくれるという点とSQLを書かずにPythonのオブジェクトを扱うように直感的にコードを記述できるという点です。

ORMを利用しておけば、MySQLやSQLite,PostgreSQLなど利用するRDBMS(relational database management system)を変更しても、そのままのコードで同じように実行することができます。

SQLAlchemyでデータを操作する前に必要なパッケージをインストールします。(Anacondaを利用している場合はSQLAlchemyが最初からインストールされているかと思います)

pip install SQLAlchemy
pip install PyMySQL

SQLAlchemyでデータベースに接続する

データベースに接続する前に、MySQLに新しいデータベースを作成しておきます。

mysql> create database example_db2;
Query OK, 1 row affected (0.01 sec)

データベースへ接続

第一引数には接続先を指定しています。今回はローカル端末のMySQLです。

第二引数のechoをTrueとしておくことでコンソールにどのようなSQLが実行されたかデバッグ情報を出力できます。

公式ドキュメント

from sqlalchemy import create_engine

engine = create_engine('mysql+pymysql://root@localhost/example_db2', echo=True)

SQLAlchemyでテーブルを作成

from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, Integer, String

engine = create_engine('mysql+pymysql://root@localhost/example_db2', echo=True)

# テーブルとのマッピングを定義
Base = declarative_base()

# テーブルとのマッピングを定義
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(20))


# 実行
Base.metadata.create_all(engine)

SQLAlchemyでデータを登録する

データを追加するには、Userクラスのインスタンスを作成して、Sessionクラスのadd()メソッドの引数に渡します。commit()メソッドを実行することで登録が確定します。

from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, Integer, String

engine = create_engine('mysql+pymysql://root@localhost/example_db2', echo=True)

# テーブルとのマッピングを定義
Base = declarative_base()

# テーブルとのマッピングを定義
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(20))

# sessionを作成
Session = sessionmaker(bind=engine)
session = Session()

# Userオブジェクトを作成
u1 = User(name='Taro')
session.add(u1)
u2 = User(name='Hanako')
session.add(u2)
session.commit()

SQLAlchemyでデータを読み込む

データ全件を読み込むには以下のように記述します。

users = session.query(User).all()
for user in users:
    print(user.id, user.name)

## 出力
1 Taro
2 Hanako

条件を指定してデータを取得するには以下のように記述します。以下の例では、usersテーブルからidが1のデータを取得しています。

user = session.query(User).filter_by(id=1).first()
print(user.id, user.name)

## 出力
1 Taro

SQLAlchemyでデータを更新する

データを更新する場合は、取得したUserオブジェクトのプロパティを変更して、Sessionオブジェクトのadd()メソッドの引数に渡します。最後にsession.commit()で確定します。

user = session.query(User).filter_by(id=1).first()
user.name = 'Jiro'
session.add(user)
session.commit()

SQLAlchemyでデータを削除する

データを削除する場合はSessionオブジェクトのdelete()メソッドを利用します。delete()メソッドの引数に削除したいUserオブジェクトを渡し、commit()メソッドで確定します。

user = session.query(User).filter_by(id=1).first()
session.delete(user)
session.commit()

まとめ

今回はPythonでデータベースを操作する方法について解説しました。

まとめ
  • mysql-connector-pythonを利用することでSQLを利用してDBの操作を行える
  • SQLAlchemyを利用することでPythonのオブジェクトを扱うようにデータを操作できる

最後まで読んでいただき、ありがとうございます。

この記事が、「面白いな」、「勉強になったな」という方は、SNSでシェアしていただけると嬉しいです。