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 ().
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?
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