ããã¯ããªã«ããããã¦æ¸ãããã®ï¼
Pythonã§ãã¼ã¿ãã¼ã¹ã¢ã¯ã»ã¹ããã¾ããã£ã¦ãã¦ããªãã®ã§ãæ å ±åéãã¦ã軽ãç·´ç¿ã«ã¨ãããã¨ã§ã
PythonããMySQLã«ã¢ã¯ã»ã¹ãã
PythonããMySQLã«ã¢ã¯ã»ã¹ããã«ã¯ãã¾ãã¯ãã©ã¤ãã¼ãæ¢ããã¨ã«ãªãã¾ãã
以åãPythonã«ããããã¼ã¿ãã¼ã¹ã¢ã¯ã»ã¹ã®ããã®æ¨æºAPIã§ããDB APIï¼PEP 249ï¼ã«ã¤ãã¦ç°¡åã«èª¿ã¹ã¾ããã
PythonのDB API 2.0(PEP 249)って? - CLOVER🍀
ãã®æã«ãMySQLã®ãã©ã¤ãã¼ãWikiã«ãªã¹ãã¢ããããã¦ããã®ãè¦ã¦ãã¾ãã
ã§ãããæ°ãå¤ãã§ããâ¦ã
調ã¹ã¦ã¿ãã¨ãå®è³ªçãªé¸æè¢ã¯æ¬¡ã®3ã¤ã®ããã§ãã
ã¡ãªã¿ã«ä»¥åããããã¨ã³ããªã¼ãæ¸ãããã¨ããã£ã¦ããã®æã«ã¯ãªãã¨ãªãMySQL Connector/Pythonã使ã£ã¦ãã¾ãã
MySQL 8.0のCharset utf8mb4での日本語環境で使うCollationで文字比較をしてみる - CLOVER🍀
ããããéããè¦ã¦ã¿ã¾ãã
mysqlclient
mysqlclientã®GitHubãªãã¸ããªã¼ã¯ãã¡ãã
GitHub - PyMySQL/mysqlclient: MySQL/MariaDB connector for Python
ããã¥ã¡ã³ãã¯ãã¡ãã
Welcome to MySQLdb’s documentation! — mysqlclient 1.2.4b4 documentation
mysqlclientã¯ãMySQLdb1ã¨ããããã¸ã§ã¯ãããã©ã¼ã¯ãããã®ã®ããã§ãã
ã¤ã³ã¹ãã¼ã«æé ãè¦ãéããMySQLã®ã¯ã©ã¤ã¢ã³ãã©ã¤ãã©ãªã¼ï¼libmysqlclientï¼ã使ããã©ã¤ãã¼ã®ããã§ãã
MySQL Connector/Python
MySQL Connector/Pythonã®GitHubãªãã¸ããªã¼ã¯ãã¡ãã
https://github.com/mysql/mysql-connector-python
ããã¥ã¡ã³ãã¯ãã¡ãã
MySQL :: MySQL Connector/Python Developer Guide
MySQL Connector/Pythonã¯ãMySQLèªä½ãæä¾ãããã©ã¤ãã¼ã§ãã
DB API 2.0以å¤ã«ããX DevAPIã¨ããå°ç¨ã®APIã使ããã¨ãã§ãã¾ãã
以åãã¡ãã使ã£ãã¨ã³ããªã¼ãæ¸ãããã¨ãããã¾ããããã¶ãMySQLãæä¾ãã¦ãããã©ã¤ãã¼ã ããã¨ããçç±ã§ä»ã調ã¹ãã«
使ã£ãæ°ããã¾ããâ¦ã
ã¤ã³ã¹ãã¼ã«ããã¨ããã¤ãã£ãã©ã¤ãã©ãªã¼ãã¤ãã¦ãã¾ãã
PyMySQL
æå¾ã¯PyMySQLã§ããGitHubãªãã¸ããªã¼ã¯ãã¡ãã
GitHub - PyMySQL/PyMySQL: MySQL client library for Python
å®ã¯mysqlclientã¨GitHub organizationãåãã§ãã
ããã¥ã¡ã³ãã¯ãã¡ãã
PyMySQL documentation — PyMySQL 0.7.2 documentation
ãã¡ãã¯Pure Pythonã®ãã©ã¤ãã¼ã®ããã§ãã
ä»åç´¹ä»ãã¦ãã3ã¤ã®ãã©ã¤ãã¼ã§ãGitHubã®ã¹ã¿ã¼æ°ã1çªå¤ãã®ããã®PyMySQLã«ãªãã¾ãã
MySQL Connector/Pythonã¯åã«1度試ãã¦ããã®ã§ãä»åã¯PyMySQLã使ã£ã¦ã¿ããã¨ã«ãã¾ãã
ç°å¢
ä»åã®ç°å¢ã¯ãã¡ãã
$ python3 --version Python 3.10.12 $ pip3 --version pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)
MySQLã¯8.4.3ã使ãã172.17.0.2ã§åä½ãã¦ãããã®ã¨ãã¾ãã
MySQL localhost:3306 ssl practice SQL > select version(); +-----------+ | version() | +-----------+ | 8.4.3 | +-----------+ 1 row in set (0.0003 sec)
æºå
ã¾ãã¯MySQLã«ãã¼ãã«ãä½æãã¾ãããé¡ã¯æ¸ç±ã«ãã¾ãããã
create table book( isbn varchar(14), title varchar(100), price int, primary key(isbn) );
次ã«ãPyMySQLãã¤ã³ã¹ãã¼ã«ãä»ã®MySQLã®ããã©ã«ãã®èªè¨¼æ¹å¼ã¯caching_sha2_passwordãªã®ã§ãPyMySQL[rsa]
ãã¤ã³ã¹ãã¼ã«ãã¾ãã
$ pip3 install PyMySQL[rsa]
åä½ç¢ºèªã¯ãã¹ãã³ã¼ãã§è¡ããã¨ã«ããã®ã§pytestãåãã§ãã¯ããã¦ããããã®ã§Mypyãã¤ã³ã¹ãã¼ã«ãã¦ããã¾ãã
$ pip3 install pytest mypy
PyMySQLã®åæ å ±ãã¤ã³ã¹ãã¼ã«ã
$ pip3 install types-PyMySQL
ã¤ã³ã¹ãã¼ã«ãããã©ã¤ãã©ãªã¼ã®ä¸è¦§ã
$ pip3 list Package Version ----------------- -------------- cffi 1.17.1 cryptography 43.0.3 exceptiongroup 1.2.2 iniconfig 2.0.0 mypy 1.13.0 mypy-extensions 1.0.0 packaging 24.1 pip 22.0.2 pluggy 1.5.0 pycparser 2.22 PyMySQL 1.1.1 pytest 8.3.3 setuptools 59.6.0 tomli 2.0.2 types-PyMySQL 1.1.0.20241103 typing_extensions 4.12.2
ç¾æç¹ã®PyMySQLã®ãã¼ã¸ã§ã³ã¯ã1.1.1ã§ããã
PyMySQLã使ã£ã¦ã¿ã
ããã§ã¯ãPyMySQLã使ã£ã¦ã¿ã¾ãããã
ããã¥ã¡ã³ãã®ã³ã¼ãä¾ãè¦ãã¨â¦å®ã¯ãããããããããã¾ããã
Examples — PyMySQL 0.7.2 documentation
ãã¨ã¯Connection
ã¨Cursor
ã®ãªãã¡ã¬ã³ã¹ã«ãªãã¾ãã
Connection Object — PyMySQL 0.7.2 documentation
Cursor Objects — PyMySQL 0.7.2 documentation
ã¡ãªã¿ã«ãã¼ã¸ã®ã¿ã¤ãã«ãè¦ãã¨ããã¼ã¸ã§ã³ã0.7.2ã«ãªã£ã¦ãã¦ã¡ãã£ã¨é©ãã®ã§ããã
GitHubãªãã¸ããªã¼å´ã®docs
ãREADME.md
ã®æ´æ°å±¥æ´ãè¦ã¦ããã¨ãããã¥ã¡ã³ãã¨ãã¦ãã以ä¸ã®æ
å ±ã¯ãªãããã§ãã
pymysql.connections.Connection
ã®èª¬æã¯ãããè¦ãã°ãããæ°ã¯ããã®ã§ãããCursor
ã«ã¤ãã¦ã¯ããã©ã«ããã©ãããåããããã®ã
ããããããªãã®ã§åããã¦ç¢ºèªãã¦ã¿ããã¨æãã¾ãããªããExamplesã§ã¯DictCursor
ã使ç¨ãã¦ãã¾ãã
ã¨ããããé²ãã¦ã¿ã¾ãããã
ãã¹ãã³ã¼ãã®import
ã«ã¯ãã¡ãã®ã¿ãè¨è¿°ã
import pymysql
æä½éã®æ å ±ã§MySQLã«æ¥ç¶ãã¦ã¿ã¾ãã
def test_connect_mysql() -> None: with pymysql.connect( host="172.17.0.2", port=3306, user="kazuhira", password="password", database="practice", ) as connection: with connection.cursor() as cursor: cursor.execute("select version() as version") result = cursor.fetchone() assert result == ("8.4.3", )
æ¥ç¶ã§ãã¾ããããCursor#fetchone
ã®çµæã¯ã¿ãã«ã§è¿ã£ã¦ãã¾ããã
ã¨ããããSQLã®å®è¡ãçµæã®åå¾ãCursor
ã使ã£ã¦è¡ããã§ããã
cursorclass
ãDictCursor
ã«ãã¦ã¿ã¾ãããã
def test_connect_mysql_dictcursor() -> None: with pymysql.connect( host="172.17.0.2", port=3306, user="kazuhira", password="password", database="practice", cursorclass=pymysql.cursors.DictCursor ) as connection: with connection.cursor() as cursor: cursor.execute("select version() as version") result = cursor.fetchone() assert result == { "version": "8.4.3", }
çµæãè¾æ¸ã«ãªãã¾ããããã¡ãã®æ¹ã使ãããããã§ããã以å¾ã¯DictCursor
ã使ããã¨ã«ãã¾ãã
次ã«ããã¼ã¿ãç»é²ãããåå¾ããããã¦ã¿ã¾ãã
ãã¬ã¼ã¹ãã«ãã¼ã使ã£ãä¾ãããã¥ã¡ã³ãã«ã¾ã£ãããªãã£ãã®ã§ãããDB API 2.0ï¼PEP 249ï¼ã®ããã¥ã¡ã³ããè¦ãã¨æå®æ¹æ³ã
æ¸ããã¦ããã®ã¨
PEP 249 â Python Database API Specification v2.0 / Module Interface / paramstyle
ãã¨ã¯ãã¹ãã³ã¼ããåèã«ãã¾ããã
https://github.com/PyMySQL/PyMySQL/blob/v1.1.1/pymysql/tests/test_basic.py
ãã¹ãã³ã¼ããããã§ãããå®éã«ä½¿ã£ã¦ã¿ãæãã ã¨ãã¬ã¼ã¹ãã«ãã¼ã®ã¹ã¿ã¤ã«ã¨ãã¦ã¯format
ã¨pyformat
ã使ããã¿ããã§ãã
insertãselectããã¨ã¯ãã¼ã¿ã®åé¤ã«truncateãªã©ã
def test_insert_select_with_placeholder() -> None: with pymysql.connect( host="172.17.0.2", port=3306, user="kazuhira", password="password", database="practice", cursorclass=pymysql.cursors.DictCursor ) as connection: with connection.cursor() as cursor: # format, tuple cursor.execute( "insert into book(isbn, title, price) values(%s, %s, %s)", ("978-4873119328", "å ¥é Python 3 第2ç", 4180, ) ) cursor.execute("select isbn, title, price from book where isbn = %s", ("978-4873119328", )) assert cursor.fetchone() == { "isbn": "978-4873119328", "title": "å ¥é Python 3 第2ç", "price": 4180 } # pyformat cursor.execute( "insert into book(isbn, title, price) values(%(isbn)s, %(title)s, %(price)s)", { "isbn": "978-4297111113", "title": "Pythonå®è·µå ¥é ââ è¨èªã®åãå¼ãåºããéçºå¹çãé«ãã (WEB+DB PRESS plusã·ãªã¼ãº)", "price": 2980 } ) cursor.execute("select isbn, title, price from book where isbn = %(isbn)s", { "isbn": "978-4297111113" }) assert cursor.fetchone() == { "isbn": "978-4297111113", "title": "Pythonå®è·µå ¥é ââ è¨èªã®åãå¼ãåºããéçºå¹çãé«ãã (WEB+DB PRESS plusã·ãªã¼ãº)", "price": 2980 } # format, list cursor.execute( "insert into book(isbn, title, price) values(%s, %s, %s)", ["978-4048930840", "ã¨ãã¹ãã¼ãPythonããã°ã©ãã³ã° æ¹è¨3ç", 4180] ) cursor.execute("select isbn, title, price from book where isbn = %s", ["978-4048930840"]) assert cursor.fetchone() == { "isbn": "978-4048930840", "title": "ã¨ãã¹ãã¼ãPythonããã°ã©ãã³ã° æ¹è¨3ç", "price": 4180 } cursor.execute("truncate table book") cursor.execute("select count(*) as count from book") assert cursor.fetchone() == { "count": 0 }
æå¾ã¯ãã©ã³ã¶ã¯ã·ã§ã³ã§ããConnection
ã«å¯¾ãã¦ã³ãããããã¼ã«ããã¯ãæ示ããããã§ããã
def test_transaction() -> None: with pymysql.connect( host="172.17.0.2", port=3306, user="kazuhira", password="password", database="practice", cursorclass=pymysql.cursors.DictCursor ) as connection: assert connection.get_autocommit() == False with connection.cursor() as cursor: # commit cursor.executemany( "insert into book(isbn, title, price) values(%(isbn)s, %(title)s, %(price)s)", [ { "isbn": "978-4873119328", "title": "å ¥é Python 3 第2ç", "price": 4180 }, { "isbn": "978-4297111113", "title": "Pythonå®è·µå ¥é ââ è¨èªã®åãå¼ãåºããéçºå¹çãé«ãã (WEB+DB PRESS plusã·ãªã¼ãº)", "price": 2980 } ] ) cursor.execute("select count(*) as count from book") assert cursor.fetchone() == { "count": 2 } connection.commit() cursor.execute("select count(*) as count from book") assert cursor.fetchone() == { "count": 2 } # rollback cursor.execute( "insert into book(isbn, title, price) values(%(isbn)s, %(title)s, %(price)s)", { "isbn": "978-4048930840", "title": "ã¨ãã¹ãã¼ãPythonããã°ã©ãã³ã° æ¹è¨3ç", "price": 4180 } ) cursor.execute("select count(*) as count from book") assert cursor.fetchone() == { "count": 3 } connection.rollback() cursor.execute("select count(*) as count from book") assert cursor.fetchone() == { "count": 2 } cursor.execute("truncate table book") cursor.execute("select count(*) as count from book") assert cursor.fetchone() == { "count": 0 }
ãããªã¨ããã§ããããã
ãããã«
PyMySQLã使ã£ã¦ãPythonããMySQLã«æ¥ç¶ãã¦ã¿ã¾ããã
PyMySQLã人æ°ã®ããã«è¦ããã®ã§ãããããã¥ã¡ã³ããå ¨ç¶ãªãã®ã§æåã¯ã¡ãã£ã¨å°ãã¾ããã
ãã£ã±ãORMã使ããã®ãªã®ã§ããããï¼