从迭代器的CSV中为django模型分配数据

时间:2013-10-20 12:28:38

标签: python django csv import

我正在从CSV中读取信息到我的django模型,但它不断抛出ValueError: Cannot assign "'Sheffield United'": "Match.home_team" must be a "Team" instance.我可以在管理界面中添加数据(可能很明显),但尝试以编程方式执行此操作会让我知道错误。

我和'联盟'有同样的问题,只是为了测试而评论 - 联盟(“E2”)对象和团队'谢菲尔德联队'存在于数据库中,因为我添加它们来测试。

然后我根据this answer.将其更改为home_team = Team.objects.get(id=row[2])。我认为这可能已经解决了最初的问题,但我现在得到:ValueError: invalid literal for int() with base 10: 'Sheffield United',这是令人困惑的,因为它是一个字符串。

Models.py:

class League (models.Model):
    name = models.CharField(max_length=2)
    last_modified = models.CharField(max_length=50)
    def __unicode__(self):
        return unicode(self.name)

class Team(models.Model):
    team_name = models.CharField(max_length=50)
    league = models.ForeignKey(League)
    team_colour = models.CharField(max_length=6, null=True, blank=True)
    def __unicode__(self):
        return unicode (self.team_name)

class Match(models.Model):
    RESULT_CHOICES = (
        ('H', 'Home'),
        ('D', 'Draw'),
        ('A', 'Away'))
    league = models.ForeignKey(League)
    match_date = models.DateTimeField()
    home_team = models.ForeignKey(Team)
    away_team = models.CharField(max_length=50)
    full_time_home_goals = models.PositiveSmallIntegerField(blank=True, null=True)
    full_time_away_goals = models.PositiveSmallIntegerField(blank=True, null=True)
    full_time_result = models.CharField(max_length=1, choices=RESULT_CHOICES, blank=True, null=True)
    half_time_home_goals = models.PositiveSmallIntegerField(blank=True, null=True)
    half_time_away_goals = models.PositiveSmallIntegerField(blank=True, null=True)
    half_time_result = models.CharField(max_length=1, choices=RESULT_CHOICES,blank=True, null=True)
    home_shots = models.PositiveSmallIntegerField(blank=True, null=True)
    away_shots = models.PositiveSmallIntegerField(blank=True, null=True)
    home_shots_on_target = models.PositiveSmallIntegerField(blank=True, null=True)
    away_shots_on_target = models.PositiveSmallIntegerField(blank=True, null=True)
    home_corners = models.PositiveSmallIntegerField(blank=True, null=True)
    away_corners = models.PositiveSmallIntegerField(blank=True, null=True)
    home_yellow = models.PositiveSmallIntegerField(blank=True, null=True)
    away_yellow = models.PositiveSmallIntegerField(blank=True, null=True)
    home_red = models.PositiveSmallIntegerField(blank=True, null=True)
    away_red = models.PositiveSmallIntegerField(blank=True, null=True)
    def __unicode__(self):
        return unicode(self.home_team) + " v " + unicode(self.away_team) + " " + unicode(self.match_date)
    class Meta:
        verbose_name_plural = "Matches"

我正在使用的管理命令是:(现在我从命令行运行它来调试它,所以已经删除了BaseCommand子类化的代码 - 它没有影响我看到的错误。 )

from django.core.management.base import BaseCommand, CommandError
import csv
import csvImporter
from core.models import Match

master_data = open ('/Users/chris/Dropbox/Django/gmblnew/data/testfile.csv', 'r') 
data = list(tuple(rec) for rec in csv.reader(master_data, delimiter=','))
from core.models import Match, League

for row in data:
    current_match = Match(
        league=row[0],
        match_date = row[1], 
        home_team = row[2],
        away_team = row[3],
        full_time_home_goals = row[4],
        full_time_away_goals = row[5],
        home_shots = row[10],
        away_shots = row[11],
        home_shots_on_target = row[12],
        away_shots_on_target = row[13],
        home_corners = row[16],
        away_corners = row[17],
        full_time_result = row[6],
    )
    print current_match 

原始追溯('必须是实例'错误:)

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 453, in execute_from_command_line
    utility.execute()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 272, in fetch_command
    klass = load_command_class(app_name, subcommand)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 77, in load_command_class
    module = import_module('%s.management.commands.%s' % (app_name, name))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/Users/chris/Dropbox/Django/gmblnew/core/management/commands/ImportCSV.py", line 24, in <module>
    full_time_result = row[6],
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/base.py", line 403, in __init__
    setattr(self, field.name, rel_obj)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/related.py", line 405, in __set__
    self.field.name, self.field.rel.to._meta.object_name))
ValueError: Cannot assign "'Sheffield United'": "Match.home_team" must be a "Team" instance.

最近的追溯:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 453, in execute_from_command_line
    utility.execute()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 272, in fetch_command
    klass = load_command_class(app_name, subcommand)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 77, in load_command_class
    module = import_module('%s.management.commands.%s' % (app_name, name))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/Users/chris/Dropbox/Django/gmblnew/core/management/commands/ImportCSV.py", line 14, in <module>
    home_team = Team.objects.get(id=row[2]),
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/manager.py", line 143, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 379, in get
    clone = self.filter(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 655, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 673, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1266, in add_q
    can_reuse=used_aliases, force_having=force_having)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1197, in add_filter
    connector)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/where.py", line 71, in add
    value = obj.prepare(lookup_type, value)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/where.py", line 339, in prepare
    return self.field.get_prep_lookup(lookup_type, value)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 322, in get_prep_lookup
    return self.get_prep_value(value)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 555, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: 'Sheffield United'

目前,我正在阅读一些初始数据进行测试,但是将CSV操作到数据库中是我将要定期进行的操作,因此需要一些指导。 (我已经看了几个CSVImporter工具 - 现在,我不想使用它们,因为我想了解我正在做的事情,我觉得我写的应该是如果我能解决这个问题就足够了。)

2 个答案:

答案 0 :(得分:3)

由于home_teamForeignKey,因此它只能接受该模型的实例;你试图传递一个字符串,这是主队的名字,这就是这个错误的含义:

ValueError: Cannot assign "'Sheffield United'": "Match.home_team" must be a "Team" instance.

在导入器脚本中,您需要搜索代表主组的对象,并将其指定为外键。您可以使用get_or_create来获取现有团队,也可以为团队名称创建新团队;像这样:

from django.core.management.base import BaseCommand, CommandError
import csv
import csvImporter
from core.models import Match

master_data = open ('/Users/chris/Dropbox/Django/gmblnew/data/testfile.csv', 'r') 
data = list(tuple(rec) for rec in csv.reader(master_data, delimiter=','))
from core.models import Match, League, Team

for row in data:
    league, _ = League.objects.get_or_create(name=row[0])
    home_team, _ = Team.objects.get_or_create(team_name=row[2], league=league)
    away_team, _ = Team.objects.get_or_create(team_name=row[3], league=league)
    current_match = Match(
        league = league,
        home_team = home_team,
        away_team = away_team,
        match_date = row[1], 
        full_time_home_goals = row[4],
        full_time_away_goals = row[5],
        home_shots = row[10],
        away_shots = row[11],
        home_shots_on_target = row[12],
        away_shots_on_target = row[13],
        home_corners = row[16],
        away_corners = row[17],
        full_time_result = row[6],
    )
    print current_match

这一行Team.objects.get_or_create(team_name=row[2])表示:

  

“尝试获取其team_name与其值相同的Team对象   row[2],如果它不存在,则创建一个新的Team对象并将其返回   代替“

get_or_create将返回一个2元组,第二部分是一个布尔值,用于告诉您是创建了新项目还是检索了现有项目。由于我们只对第一部分感兴趣,因此我更新了代码以仅使用实例并忽略第二个值。

答案 1 :(得分:1)

试试home_team = Team.objects.get(team_name=row[2])。问题来自于Team.id字段是一个整数字段(因为没有定义primary_key字段,django会自动创建一个整数id字段)并且您要分配一个字符串它