web-dev-qa-db-fra.com

Comment insérer correctement les caractères utf-8 dans une table MySQL en utilisant python

Je suis extrêmement confus et perplexe devant la façon dont je stocke des chaînes contenant des caractères inhabituels (pour quelqu'un qui a l'habitude de traiter avec un jeu de caractères anglais britannique).

Voici mon exemple.

J'ai ce nom: Bientôt l'été

Voici comment j'ai créé ma table:

CREATE TABLE MyTable(
    'my_id' INT(10) unsigned NOT NULL,
    'my_name' TEXT CHARACTER SET utf8 NOT NULL,
    PRIMARY KEY(`my_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

En utilisant ce script python simplifié, j'essaie d'insérer la chaîne dans une base de données et une table MySQL:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import MySQLdb

mystring = "Bientôt l'été"

myinsert = [ { "name" : mystring.encode("utf-8").strip()[:65535], "id" : 1 } ]

con = None
con = MySQLdb.connect('localhost', 'abc', 'def', 'ghi');
cur = con.cursor()
sql = "INSERT INTO 'MyTable' ( 'my_id', 'my_name' ) VALUES ( %(id)s, %(name)s ) ; "
cur.executemany( sql, myinsert )
con.commit()
if con: con.close()

Si je tente ensuite de lire le nom dans la base de données, il est enregistré sous la forme: Bientôt l'été

Je veux qu'il se lise: Bientôt l'été

Comment puis-je obtenir le script python/base de données MySQL pour le faire? Je pense que cela a quelque chose à voir avec le jeu de caractères et la façon dont il est défini, mais je ne trouve pas une simple page Web expliquant cela sans jargon technique. Je lutte avec ça depuis des heures!

J'ai regardé ceci et je vois que character_set_server est défini comme latin1 mais je ne sais pas s'il s'agit du problème ni comment le résoudre:

mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
10
user1464409

Avez-vous essayé, cette requête set names utf8;

#!/usr/bin/python
# -*- coding: utf-8 -*-

import MySQLdb

mystring = "Bientôt l'été"

myinsert = [{ "name": mystring.encode("utf-8").strip()[:65535], "id": 1 }]

con = MySQLdb.connect('localhost', 'abc', 'def', 'ghi');
cur = con.cursor()

cur.execute("set names utf8;")     # <--- add this line,

sql = "INSERT INTO 'MyTable' ( 'my_id', 'my_name' ) VALUES ( %(id)s, %(name)s ) ; "
cur.executemany( sql, myinsert )
con.commit()
if con: con.close()
9
Adem Öztaş

Définissez le jeu de caractères client par défaut:

<?php
$con=mysqli_connect("localhost","my_user","my_password","my_db");
// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

// Change character set to utf8
mysqli_set_charset($con,"utf8");
mysqli_close($con);
?>
4
Iman Marashi

Votre problème réside dans la façon dont vous affichez les données lorsque vous les lisez dans la base de données. Vous regardez les données UTF-8 interprétées à tort comme Latin 1.

>>> "Bient\xf4t l'\xe9t\xe9"
"Bientôt l'été"
>>> "Bient\xf4t l'\xe9t\xe9".encode('utf8').decode('latin1')
"Bientôt l'été"

Ce qui précède a codé une chaîne unicode en UTF-8, puis l’interprète de manière erronée comme étant Latin 1 (ISO 8859-1), et les codages ô et é, codés en deux octets UTF-8 chacun, sont réinterprétés en deux caractères latins. 1 code pointe chacun.

Puisque vous utilisez Python 2, vous ne devriez pas avoir besoin de .encode() déjà encoder des données. Il serait préférable que vous insériez plutôt des objets unicode; vous voulez donc décoder à la place:

myinsert = [ { "name" : mystring.decode("utf-8").strip()[:65535], "id" : 1 } ]

En appelant .encode() sur les données codées, vous demandez à Python de commencer par décoder les données (en utilisant le codage par défaut) afin qu’elles puissent ensuite coder pour vous. Si la valeur par défaut de votre python a été changée en latin1, vous obtiendrez le même effet. Les données UTF-8 interprétées en tant que Latin 1 avant d’être recodées en Latin-1.

Vous voudrez peut-être lire sur Python et Unicode:

3
Martijn Pieters
<?php
//Set Beginning of php code:
header("Content-Type: text/html; charset=UTF-8");
mysql_query("SET NAMES 'utf8'"); 
mysql_query('SET CHARACTER SET utf8');

//then create the connection 
$CNN=mysql_connect("localhost","usr_Urdu","123") or die('Unable to Connect');
$DB=mysql_select_db('db_Urdu',$CNN)or die('Unable to select DB');
1
Naeem