从迭代器的CSV中将数据分配给django模型 [英] Assigning data to django model from CSV from iterator

查看:243
本文介绍了从迭代器的CSV中将数据分配给django模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从CSV中读取信息到我的django模型,但它不断抛出 ValueError:无法分配谢菲尔德联队:Match.home_team必须是团队实例。我可以在管理界面添加数据罚款(可能显然),但试图以编程方式给我这个错误。

I'm reading info in from a CSV to my django model, but it keeps throwing an ValueError: Cannot assign "'Sheffield United'": "Match.home_team" must be a "Team" instance. I can add data fine in the admin interface (perhaps obviously), but trying to do it programmatically gives me that error.

我对'League'有同样的问题,并且评论它只是为了测试 - 联盟(E2)对象和Team'Sheffield United'数据库,因为我添加他们来测试。

I had the same issue with 'League', and commented it out just to test - both the league ("E2") object and Team 'Sheffield United' exist in the database, as I added them to test that.

然后将它们更改为 home_team = Team.objects.get(id = row [2])按照此答案。我认为这可能解决了初始问题,但我现在得到: ValueError:无效的文字int()与基地10:'谢菲尔德联合',这是令人不安,因为它一个字符串。

I then changed them to, for example home_team = Team.objects.get(id=row[2]) as per this answer.. I think that may have solved the initial problem, but I now get: ValueError: invalid literal for int() with base 10: 'Sheffield United', which is baffling as it's a string.

Models.py:

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从这个代码子类化 - 它不会影响我看到的错误。)

The management command that I'm using is: (right now I'm running it from the commandline to debug it, so have stripped the BaseCommand subclassing out of this code - it didn't affect the error I was seeing.)

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 

原始追踪(必须是执行个体的错误:)

Original traceback (on 'must be an instance' error:)

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工具 - 现在,我不想使用它们,因为我想了解我在做什么的胆量,我觉得我写的应该是)

At the moment, I'm reading in some initial data for testing, but manipulating CSVs into the database is something that I'll be doing regularly, so some guidance would be appreciated. (I've had a look at a couple of CSVImporter tools - right now, I don't want to use them, as I want to understand the guts of what I'm doing, and I feel like what I've written should suffice, if I can get past this problem.)

推荐答案

由于 home_team ForeignKey ,它只能接受该模型的实例;您尝试传递一个字符串,这是主队的名称,这是此错误的含义:

Since home_team is a ForeignKey, it can only accept instances of that model; you are trying to pass it a string which is the name of the home team, that's what this error means:

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

在您的导入程序脚本中,您需要搜索代表主队,并将其分配为外键。您可以使用 get_or_create 取得现有小组,或为小组名称建立新小组;像这样:

In your importer script, you need to search for the object that represents the home team, and assign that as the foreign key. You can use get_or_create to either fetch an existing team, or create a new team for the team name; like this:

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


$ b b

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


尝试获取一个Team_name与
row [2] 的值相同的Team对象,如果它不存在,创建一个新的Team对象并返回它
而不是

"Try to get a Team object whose team_name is the same as the value for row[2], if it doesn't exist, create a new Team object and return it instead"

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

get_or_create will return a 2-tuple, and the second part is a boolean to tell you if a new item was created or an existing item retrieved. Since we are only interested in the first part, I updated the code to only use the instance and ignore the second value.

这篇关于从迭代器的CSV中将数据分配给django模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆