Python sqlite3.ProgrammingError: Vous ne devez pas utiliser 8 bits bytestrings sauf si vous utilisez un text_factory qui peut interpréter de 8 bits bytestrings
Je suis en train d'écrire un script qui scanne un répertoire de façon récursive et de les stocker dans un dictionnaire est une collection de liste. Cette liste de sternes contenir la liste qui a nom de fichier et la taille du fichier. Ce nom de fichier peut contenir des caractères UTF-8 comme indiqué ci-dessous.
['test.rus (\xd0\xa5\xd0\xb5\xd0\xbb\xd1\x8c\xd1\x88\xd0\xb8).srt', 23930]
test.rus (Хельши).srt
Maintenant, tout en essayant d'insérer les données dans la base de données, j'obtiens l'erreur comme ci-dessous
Traceback (most recent call last):
File "filedup.py", line 267, in <module>
read_file_directory(directory)
File "filedup.py", line 118, in read_file_directory
(values[i][0], each, values[i][1]))
sqlite3.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.
La fonction d'effectuer cette opération est donnée ci-dessous
from collections import defaultdict
dirDict = defaultdict(list)
def read_file_directory(path):
global dirDict
logger.debug("Path being scanned %s" %path)
fileStats = []
for root, subFolders, files in os.walk(path):
for file_name in files:
fileStats = []
fileStats.insert(0, file_name)
fileSize = os.path.getsize(os.path.join(root,file_name))
fileStats.insert(1, fileSize)
dirDict[root].append(fileStats)
#Insert the data in DB
cursor = dbHandler.cursor()
keys = dirDict.keys()
for each in keys:
values = dirDict[each]
print values
for i in xrange(len(values)):
print values[i]
print values[i][0]
print values[i][1]
fileName = values[i][0]
fileSize = values[i][1]
cursor.execute("insert or ignore into master \
(FileName, FilePath, FileSize) values(?,?,?)", \
(values[i][0], each, values[i][1]))
logger.debug("Insert data for %s, %s, %s" %(values[i][0], each, values[i][1]))
Maintenant que je suis en train d'apprendre le langage Python, je ne reçois pas comment résoudre ce problème. La version de Python que j'utilise est donnée ci-dessous
$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Donc toutes les pensées comment fixer avec la version actuelle de Python comme je suis à la recherche pour générique correctif de sorte qu'il peut être un travail, même sur les versions supérieures.
J'ai aussi observé qu'en raison de cette erreur aucune des données est insérée dans la base de données. Alors, comment puis-je m'assurer que, même si une opération suite à une erreur de la précédente, les données peuvent être insérées dans la base de données.
unicode
?Pas de raison que je puisse utiliser l'unicode sans aucun problème.
Pas lié à votre problème réel, mais que
global dirDict
n'est pas un bon style. Il est préférable de passer dirDict
dans la fonction, de sorte que c'est la signature devient def read_file_directory(path, dirDict)
, ou, si dirDict
n'est pas nécessaire avant read_file_directory()
est appelé, créer read_file_directory()
et de retour de cette fonction.Merci je vais mettre à jour le même. Mais un rapide est des références de travail sans erreurs que je veux utiliser dirDict à plusieurs endroits une fois qu'il est rempli de read_file_directory fonction. Désolé si cela est novice question que j'ai encore à apprendre Python.
dans ce cas, il suffit de créer
dirDict
dans read_file_directory()
et de le retourner. Le code qui appelle la fonction serait alors ceci: dirDict = read_file_directory('path/path/path')
OriginalL'auteur Abhinav | 2014-10-04
Vous devez vous connecter pour publier un commentaire.
La
sqlite
exception vous recommande de passer à des chaînes unicode, donc vous devriez le faire.Python inscription à l'annuaire des fonctions telles que
os.walk
a un curieuse propriété; ils seront de retour normal des chaînes lors de la normale des cordes, et le retour des chaînes unicode lorsque des chaînes unicode. Par conséquent, lors de l'utilisation deos.walk(path)
comme dans votre code, vous devez vous assurer quepath
est une chaîne unicode.Pour ce faire, vous pouvez convertir explicitement unicode à l'aide de la
unicode()
fonction, par exemple en écrivantpath = unicode(path)
avant l'appel àos.walk
.Aussi, vous devez appeler
cursor.commit()
dans votre code à écrire dans la base de données. L'appeler une fois après que vous avez fini de les passer en boucle sur tous les noms de fichiers doivent être suffisantes.cursor.execute("insert or ignore into master \ (FileName, FilePath, FileSize) values(?,?,?)", \ (values[i][0].decode('utf-8'), each.decode('utf-8'), values[i][1]))
Mais je veux faire en unicode afin que dans l'avenir nous ne se retrouvent pas dans les autres erreursil dépend. Comment appelez-vous cette fonction?
L'appel de la fonction est
read_file_directory(directory)
Le répertoire sera passée en tant que partie de l'argument du script.J'ai édité la réponse.
OriginalL'auteur parchment
Essayez de changer la ligne:
à
cursor.execute("insert or ignore into master \ (FileName, FilePath, FileSize) values(?,?,?)", \ (values[i][0].decode('utf-8'), each.decode('utf-8'), values[i][1]))
de Sorte que les œuvres.il pourrait fonctionner, mais il est probablement mieux de le convertir au format unicode aussi tôt que possible, de cette façon vous traitez avec unicode en interne. @parchemin pourriez avoir un bon point sur unicode à l'aide d'un chemin d'accès comme un argument de
os.walk()
- vous devez vérifier que trop.Ok, donc j'ai mis à jour le code que
path = unicode(directory) read_file_directory(path)
et il a travaillé avec l'aide d'decode('utf-8')
méthode. Toutes les valeurs s'insérés dans la base de données sans erreur.Bien que la documentation ne mentionne pas explicitement
os.walk()
, j'ai vérifié à l'aide d'une unicode argument de chemin deos.walk
et il fonctionne comme un parchemin décrit. C'est probablement la façon la plus propre à résoudre le problème.oh, OK, alors.
OriginalL'auteur mhawke