Évitez UnicodeEncodeError lors du lancement de requêtes avec le japonais dans MySQLdb de Python

Aperçu

Il y a des moments où vous souhaitez lancer une instruction d'insertion de Python vers MySQL. Lorsque j'utilise le package MySQLdb pour soumettre une requête, j'obtiens un UnicodeEncodeError si la requête contient du japonais. Il semble que cela puisse être évité en ajoutant les options "use_unicode = True" et "charset =" utf8 "" à l'argument de MySQLdb.connect ().

Statut

Supposons que vous ayez une base de données MySQL comme celle-ci.

mysql> desc test;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| test_id   | int(11)     | NO   | PRI | NULL    |       |
| test_text | varchar(64) | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+

Depuis Python, je voulais ajouter une chaîne à la colonne appelée test_text. Essayez de lancer une instruction d'insertion en utilisant le package MySQLdb normalement.

mysqltest.py


import MySQLdb
 
try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password
    )

    cur = conn.cursor()

    query = "insert into test values('1','aaa')"

    cur.execute(query)
    
except:
    cur.close()
    conn.close()

cur.close()
conn.commit()
conn.close()

Vous pouvez le faire normalement avec une chaîne de caractères alphabétiques.

mysql> select * from test;
+---------+-----------+
| test_id | test_text |
+---------+-----------+
|       1 | aaa       |
+---------+-----------+

Cependant, s'il s'agit d'une chaîne de caractères japonais ...

mysqltest.py


(réduction)
    query = "insert into test values('2','Ah ah')"

    cur.execute(query)
(réduction)
Traceback (most recent call last):
  File "mysqltest.py", line 30, in <module>
    conn.commit()
_mysql_exceptions.OperationalError: (2006, '')

J'obtiens une erreur comme Cela semble être une erreur que j'ai eue en essayant de conn.commit () après avoir détecté une exception dans l'instruction try. Je ne suis pas sûr de cette trace de pile, alors émettons une trace de pile lorsque l'instruction except est exécutée.

mysqltest.py


import MySQLdb
import traceback

try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password
    )

    cur = conn.cursor()

    query = "insert into test values('2','Ah ah')"

    cur.execute(query)

except:
    cur.close()
    conn.close()
    print(traceback.format_exc()) 

cur.close()
conn.commit()
conn.close()

Ensuite, ça sortira comme ça.

Traceback (most recent call last):
  File "mysqltest.py", line 25, in <module>
    cur.execute(query)
  File "C:\path\to\anaconda\lib\site-packages\MySQLdb\cursors.py", line 248, in execute
    query = query.encode(db.encoding, 'surrogateescape')
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 29-31: ordinal not in range(256)

Je me fâche que la requête ne puisse pas être encodée avec le code de caractère latin-1. Apparemment, le package MySQLdb encode en utilisant latin-1 par défaut. Pourquoi?

Contre-mesures

Si vous vous référez à here, il semble que vous puissiez spécifier la méthode d'encodage avec l'argument de MySQLdb.connect (). .. Si vous donnez "use_unicode = True" et "charset =" utf8 "" comme arguments,

mysqltest.py


import MySQLdb
import traceback

try: 
    conn = MySQLdb.connect(
    host=host,
    db=dbname,
    port=port,
    user=user,
    passwd=password,
    use_unicode=True,
    charset="utf8"
    )

    cur = conn.cursor()

    query = "insert into test values('2','Ah ah')"

    cur.execute(query)

except:
    cur.close()
    conn.close()
    print(traceback.format_exc()) 

cur.close()
conn.commit()
conn.close()

La requête a été encodée avec succès dans utf-8 et cela a fonctionné.

mysql> select * from test;
+---------+-----------+
| test_id | test_text |
+---------+-----------+
|       1 | aaa       |
|       2 |Ah ah|
+---------+-----------+

Recommended Posts

Évitez UnicodeEncodeError lors du lancement de requêtes avec le japonais dans MySQLdb de Python
Gère les caractères japonais UTF-8 dans la base de données MySQL de Python.
Sortie japonaise lors de l'utilisation de python dans Visual Studio
Comment ne pas échapper au japonais en traitant avec JSON en Python
Faites attention à LANG pour UnicodeEncodeError lors de l'impression du japonais avec Python 3
Comportement lors du retour dans le bloc with
Mettez les polices japonaises dans les images avec Colaboratory
Decorator pour éviter UnicodeEncodeError dans Python 3 print ()