PythonでMySQLに接続する方法!pymysqlの基本的な使い方
生徒
「先生、PythonからMySQLデータベースに接続することはできますか?」
先生
「もちろんです!Pythonにはpymysqlという便利なライブラリがあって、これを使えばMySQLデータベースに簡単に接続できますよ。」
生徒
「MySQLって何ですか?SQLiteとは違うんですか?」
先生
「MySQLは、世界中で広く使われている本格的なデータベース管理システムです。SQLiteよりも大規模なデータを扱えて、複数のユーザーが同時にアクセスできるという特徴があります。それでは、pymysqlの使い方を詳しく見ていきましょう!」
1. MySQLとpymysqlの基礎知識
MySQL(マイエスキューエル)は、オープンソースのリレーショナルデータベース管理システム(RDBMS)です。Webアプリケーションやビジネスシステムなど、さまざまな場面で活用されています。
pymysql(パイマイエスキューエル)は、PythonからMySQLデータベースに接続するためのライブラリです。Pure Pythonで実装されているため、インストールが簡単で、クロスプラットフォームで動作します。
MySQLの主な特徴
- 大規模なデータベースに対応:数百万件以上のデータも高速処理
- マルチユーザー対応:複数のユーザーが同時にアクセス可能
- トランザクション機能:データの整合性を保証
- 高い信頼性:企業システムでも広く採用されている
2. pymysqlのインストール方法
pymysqlを使うには、まずライブラリをインストールする必要があります。ターミナル(Windowsではコマンドプロンプト)を開いて、以下のコマンドを実行してください。
pip install pymysql
このコマンドを実行すると、自動的にpymysqlライブラリがダウンロードされてインストールされます。pipは、Pythonのパッケージ管理ツールで、様々なライブラリを簡単にインストールできます。
インストールの確認方法
正しくインストールされたか確認するには、Pythonを起動して以下のコードを実行してみましょう:
import pymysql
print("pymysqlのバージョン:", pymysql.__version__)
print("インストール成功!")
エラーが出なければ、pymysqlが正しくインストールされています。
3. MySQLデータベースへの接続方法
pymysqlを使ってMySQLデータベースに接続するには、データベースサーバーの情報(ホスト名、ユーザー名、パスワードなど)が必要です。
import pymysql
# MySQLデータベースに接続
connection = pymysql.connect(
host='localhost', # データベースサーバーのホスト名
user='root', # ユーザー名
password='password123', # パスワード
database='test_db', # 接続するデータベース名
charset='utf8mb4' # 文字コード
)
print("MySQLデータベースに接続しました")
# 接続を閉じる
connection.close()
print("接続を閉じました")
このコードでは、pymysql.connect()関数を使ってMySQLサーバーに接続しています。各パラメータの意味は以下の通りです:
host:MySQLサーバーが動いているコンピュータの場所(localhostは自分のパソコン)user:データベースにログインするためのユーザー名password:ユーザー名に対応するパスワードdatabase:接続先のデータベース名charset:日本語などの文字を正しく扱うための文字コード設定
接続が完了したら、必ずclose()メソッドで接続を閉じることが重要です。これにより、サーバーのリソースを適切に解放できます。
4. テーブルの作成とデータの挿入
データベースに接続したら、次はテーブルを作成してデータを保存してみましょう。テーブルは、データを整理して保存するための表のようなものです。
import pymysql
connection = pymysql.connect(
host='localhost',
user='root',
password='password123',
database='test_db',
charset='utf8mb4'
)
# カーソルオブジェクトを作成
cursor = connection.cursor()
# テーブルを作成するSQL文
create_table_sql = """
CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price INT,
stock INT
)
"""
# テーブルを作成
cursor.execute(create_table_sql)
print("テーブルを作成しました")
# データを挿入
insert_sql = "INSERT INTO products (name, price, stock) VALUES (%s, %s, %s)"
products_data = [
('ノートパソコン', 89800, 15),
('ワイヤレスマウス', 2980, 50),
('キーボード', 5800, 30)
]
# 複数のデータを一度に挿入
cursor.executemany(insert_sql, products_data)
connection.commit()
print(f"{cursor.rowcount}件のデータを挿入しました")
# 接続を閉じる
cursor.close()
connection.close()
cursorは、データベースに対して命令を送るための道具です。カーソルを使って、SQL文を実行します。
pymysqlでは、プレースホルダーとして%sを使用します。これは、後から実際の値を安全に埋め込むための印です。
commit()メソッドは、データベースへの変更を確定させるために必要です。これを実行しないと、挿入したデータが保存されません。
5. データの取得(SELECT)と表示
データベースに保存したデータを取り出して表示する方法を学びましょう。SELECT文を使うことで、必要なデータを検索できます。
import pymysql
connection = pymysql.connect(
host='localhost',
user='root',
password='password123',
database='test_db',
charset='utf8mb4'
)
cursor = connection.cursor()
# すべてのデータを取得
cursor.execute("SELECT * FROM products")
all_products = cursor.fetchall()
print("=== 全商品情報 ===")
for product in all_products:
print(f"ID: {product[0]}, 商品名: {product[1]}, 価格: {product[2]}円, 在庫: {product[3]}個")
# 条件を指定してデータを取得
cursor.execute("SELECT name, price FROM products WHERE price < %s", (10000,))
cheap_products = cursor.fetchall()
print("\n=== 10000円未満の商品 ===")
for product in cheap_products:
print(f"商品名: {product[0]}, 価格: {product[1]}円")
cursor.close()
connection.close()
fetchall()メソッドは、実行結果のすべての行を取得します。結果はタプルのリストとして返されるため、for文で1行ずつ処理できます。
WHERE句を使うことで、条件に合致するデータだけを取得できます。例えば、「価格が10000円未満の商品」という条件を指定しています。
辞書形式でデータを取得する方法
データを辞書形式で取得すると、列名でアクセスできるため便利です。DictCursorを使用します:
import pymysql.cursors
connection = pymysql.connect(
host='localhost',
user='root',
password='password123',
database='test_db',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
cursor = connection.cursor()
cursor.execute("SELECT * FROM products")
products = cursor.fetchall()
for product in products:
print(f"商品名: {product['name']}, 価格: {product['price']}円")
cursor.close()
connection.close()
DictCursorを使うと、列名をキーとした辞書形式でデータを取得できるため、コードがより読みやすくなります。
6. データの更新(UPDATE)と削除(DELETE)
既存のデータを変更したり、不要なデータを削除したりする方法を見ていきましょう。
データの更新
import pymysql
connection = pymysql.connect(
host='localhost',
user='root',
password='password123',
database='test_db',
charset='utf8mb4'
)
cursor = connection.cursor()
# 商品の価格を更新
update_sql = "UPDATE products SET price = %s WHERE name = %s"
cursor.execute(update_sql, (3500, 'ワイヤレスマウス'))
connection.commit()
print(f"{cursor.rowcount}件のデータを更新しました")
# 在庫数を増やす
cursor.execute("UPDATE products SET stock = stock + %s WHERE id = %s", (10, 1))
connection.commit()
print("在庫を更新しました")
cursor.close()
connection.close()
UPDATE文では、SETで変更する列と新しい値を指定し、WHEREで更新対象のレコードを指定します。
データの削除
import pymysql
connection = pymysql.connect(
host='localhost',
user='root',
password='password123',
database='test_db',
charset='utf8mb4'
)
cursor = connection.cursor()
# 在庫がゼロの商品を削除
delete_sql = "DELETE FROM products WHERE stock = %s"
cursor.execute(delete_sql, (0,))
connection.commit()
print(f"{cursor.rowcount}件のデータを削除しました")
cursor.close()
connection.close()
DELETE文を使う際は、WHERE句を必ず指定してください。WHERE句を忘れると、テーブル内のすべてのデータが削除されてしまいます。
7. トランザクション処理の実装
トランザクションは、複数のデータベース操作をひとまとまりとして扱う仕組みです。すべての操作が成功した場合のみ変更を確定し、途中でエラーが発生した場合はすべての変更を取り消します。
import pymysql
connection = pymysql.connect(
host='localhost',
user='root',
password='password123',
database='test_db',
charset='utf8mb4'
)
cursor = connection.cursor()
try:
# トランザクション開始
connection.begin()
# 商品の在庫を減らす
cursor.execute("UPDATE products SET stock = stock - %s WHERE id = %s", (5, 1))
# 別の商品の在庫を増やす
cursor.execute("UPDATE products SET stock = stock + %s WHERE id = %s", (3, 2))
# すべて成功したらコミット
connection.commit()
print("トランザクションが正常に完了しました")
except Exception as e:
# エラーが発生したらロールバック(変更を取り消す)
connection.rollback()
print(f"エラーが発生しました: {e}")
print("すべての変更を取り消しました")
finally:
cursor.close()
connection.close()
rollback()メソッドを使うと、トランザクション内で行ったすべての変更を取り消すことができます。これにより、データの整合性を保つことができます。
例えば、在庫の移動処理で片方だけ成功してもう片方が失敗した場合、ロールバックによって両方の変更が取り消されるため、データの不整合を防げます。
8. with文を使った安全な接続管理
pymysqlでも、with文を使うことで、より安全にデータベース接続を管理できます。自動的に接続を閉じてくれるため、リソースリークを防げます。
import pymysql
try:
with pymysql.connect(
host='localhost',
user='root',
password='password123',
database='test_db',
charset='utf8mb4'
) as connection:
with connection.cursor() as cursor:
# データを取得
cursor.execute("SELECT COUNT(*) FROM products")
count = cursor.fetchone()[0]
print(f"商品数: {count}件")
# 新しい商品を追加
insert_sql = "INSERT INTO products (name, price, stock) VALUES (%s, %s, %s)"
cursor.execute(insert_sql, ('USBメモリ', 1580, 100))
connection.commit()
print("商品を追加しました")
except pymysql.MySQLError as e:
print(f"データベースエラー: {e}")
except Exception as e:
print(f"予期しないエラー: {e}")
with文を使うと、ブロックを抜けるときに自動的に接続とカーソルが閉じられます。エラーが発生した場合でも、確実にリソースが解放されるため安全です。
9. エラー処理のベストプラクティス
データベース操作では、さまざまなエラーが発生する可能性があります。適切なエラー処理を実装することで、プログラムの安定性が向上します。
主なエラーの種類
pymysql.err.OperationalError:接続エラーやサーバーエラーpymysql.err.ProgrammingError:SQL文の構文エラーpymysql.err.IntegrityError:データの整合性エラー(重複キーなど)pymysql.err.DataError:データ型の不一致エラー
%s)を使用してください。ユーザー入力を直接SQL文に埋め込むと、SQLインジェクション攻撃という深刻なセキュリティ脆弱性が生じます。
10. 実践的なデータベース操作のコツ
pymysqlを効果的に使うための重要なポイントをまとめました。
接続プールの活用
頻繁にデータベースに接続する場合は、接続プールを使うことで、パフォーマンスを向上させることができます。毎回新しい接続を作成するオーバーヘッドを削減できます。
インデックスの活用
大量のデータを扱う場合は、適切なインデックスを設定することで、検索速度が大幅に向上します。特に、WHERE句で頻繁に使用する列にはインデックスを設定しましょう。
プリペアドステートメントの使用
プレースホルダーを使ったSQL文は、プリペアドステートメントとして実行されます。これにより、セキュリティが向上し、同じSQL文を繰り返し実行する場合のパフォーマンスも向上します。
適切なエンコーディング設定
日本語を扱う場合は、charset='utf8mb4'を必ず指定してください。utf8mb4は、絵文字を含むすべてのUnicode文字を正しく扱えます。
データベース接続情報の管理
パスワードなどの接続情報は、ソースコードに直接書かずに、環境変数や設定ファイルで管理することをおすすめします。セキュリティ上、GitHubなどにパスワードをアップロードしないよう注意してください。