Django verision 1.9,DB backend:sqlite3。
我很难弄清楚如何处理这个错误。我将主鸟类物种列表(available here)导入到一组Django模型中。我的导入进展顺利,但是当我尝试将此值Rüppell's Vulture
保存到模型中时崩溃了。目标字段的定义如下:
species_english = models.CharField(max_length=100, default=None, blank=True, null=True)
这里有错误:
ProgrammingError:除非使用a,否则不得使用8位字节串 text_factory,可以解释8位字节串(如text_factory = STR)。强烈建议您只需切换即可 应用于Unicode字符串。
我正在阅读有关unicode字符串的Django's documentation。这开始就像这样:
Django原生支持各处的Unicode数据。提供你的 数据库可以以某种方式存储数据,您可以安全地传递 Unicode字符串到模板,模型和数据库。
同时查询information关于此字符:ü
,它的表示形式是unicode和utf-8。
将此字符串保存到数据库的方法非常简单,我只是使用csv.reader
解析CSV文件:
new_species = Species(genus=new_genus, species=row[4], species_english=row[7])
错误抛出字符串包含在row[7]
中。我错过了为什么数据库不允许这个角色?
更新
这是导入数据的整个脚本的内容:
import csv
from birds.models import SpeciesFile, Order, Family, Genus, Species, Subspecies
csv_file = str(SpeciesFile.objects.all()[0].species_list)
#COLUMNS
#0 - Order
#1 - Family Scientific
#2 - Family (English)
#3 - Genus
#4 - Species
#5 - SubSpecies
with open("birds/media/"+csv_file.split('/')[1], 'rU') as c:
Order.objects.all().delete()
Family.objects.all().delete()
Genus.objects.all().delete()
Species.objects.all().delete()
Subspecies.objects.all().delete()
reader = csv.reader(c, delimiter=';', quotechar='"')
ini_rows = 4
for row in reader:
if ini_rows > 0:
ini_rows -= 1
continue
if row[0]:
new_order = Order(order=row[0])
new_order.save()
elif row[1]:
new_fam = Family(order = new_order, family_scientific=row[1], family_english=row[2])
new_fam.save()
elif row[3]:
new_genus = Genus(family = new_fam, genus=row[3])
new_genus.save()
elif row[4]:
print row[4]
new_species = Species(genus=new_genus, species=row[4], species_english=row[7])
new_species.save()
elif row[5]:
print row[5]
new_subspecies = Subspecies(species=new_species, subspecies=row[5])
new_subspecies.save()
以下是models.py文件定义:
from __future__ import unicode_literals
from django.db import models
class SpeciesFile(models.Model):
species_list = models.FileField()
class Order(models.Model):
order = models.CharField(max_length=100)
def __str__(self):
return self.order
class Family(models.Model):
order = models.ForeignKey(Order)
family_scientific = models.CharField(max_length=100)
family_english = models.CharField(max_length=100)
def __str__(self):
return self.family_english+" "+self.family_scientific
class Genus(models.Model):
family = models.ForeignKey(Family)
genus = models.CharField(max_length=100)
def __str__(self):
return self.genus
class Species(models.Model):
genus = models.ForeignKey(Genus, default=None)
species = models.CharField(max_length=100, default=None)
species_english = models.CharField(max_length=100, default=None, blank=True, null=True)
def __str__(self):
return self.species+" "+self.species_english
class Subspecies(models.Model):
species = models.ForeignKey(Species)
subspecies = models.CharField(max_length=100)
def __str__(self):
return self.subspecies
答案 0 :(得分:2)
Django CharField是一种面向字符的格式。您需要传递Unicode字符串。
CSV是一种面向字节的格式。当您从CSV文件中读取数据时,您将获得字节字符串。
要从字节到字符,您必须知道在导出CSV文件时将原始字符转换为字节时使用的编码。理想情况下,这将是UTF-8,但如果文件来自Excel,它可能不会。也许它是Windows-1252(西欧安装的'ANSI'代码页)。也许它是别的东西。
(当你只有ASCII字节(字节0-127)时,Django / Python 2可以让你将字节串写入Unicode属性,因为它们在批量编码中具有相同的映射.ASCII是'最佳猜测'尽我所能,但它不可靠,如果你尝试,Python 3更喜欢引发错误。)
所以:
new_order = Order(order=row[0].decode('windows-1252'))
或者,一次解码整行:
row = [s.decode('windows-1252') for s in row]