2013-10-20 53 views
0

我正在從CSV讀取信息到我的django模型,但它一直拋出ValueError: Cannot assign "'Sheffield United'": "Match.home_team" must be a "Team" instance.我可以在管理界面中添加數據(可能很明顯),但嘗試做它以編程方式給我那個錯誤。從迭代器的CSV分配數據到django模型

我與'聯賽'有同樣的問題,並且只是爲了測試而評論 - 聯賽(「E2」)對象和團隊'謝菲聯隊'存在於數據庫中,因爲我添加了它們來測試。

然後,我將其更改爲,例如home_team = Team.objects.get(id=row[2])根據this answer.。我認爲這可能已經解決了最初的問題,但我現在得到: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工具 - 現在,我不想使用它們,因爲我想了解我正在做的事情的膽量,而且我覺得我寫的應該是如果我能夠通過這個問題就足夠了)。

回答

3

由於home_teamForeignKey,它只能接受該模型的實例;你想傳遞一個這是主隊的名字,這就是這個錯誤是指:

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

在你的進口商腳本,你需要搜索對象表示home團隊,並將其分配爲外鍵。您可以使用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])意味着:

"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元組,而第二部分是一個布爾值來告訴你,如果一個新項目創建或現有項目檢索。由於我們只對第一部分感興趣,因此我更新了代碼以僅使用實例並忽略第二個值。

+0

這現在已經開始了 - 雖然我可能已經接受得太早了。它貫穿始終,並保存第一場比賽,但是當它進入第二次迭代並且看着聯盟時,它會拋出'django.db.utils.IntegrityError:core_team.league_id可能不是NULL' - 我絕對不會問它爲NULL! (我在日期列中添加了一些驗證,並且這在第二行中有效,所以它不是像我以前的一些問題那樣,關於文件末尾的換行符char。) – Withnail

+0

這意味着列是空的,''a',,'c','d','e'' –

+0

這絕對不是空 - 數據的第二行/第三個文件是'E2,03/08/2013,布裏斯托爾市,布拉德福,2, 2,D,1,1,D,12,10,5,2,8,11' - 與第一行格式相同。但是,我回去刪除了之前半工作代碼放入的測試數據(匹配和團隊),現在第一行出現相同的錯誤 - 它不再創建Match實例。任何想法,還是我應該做一個新的問題?回溯指向'gmblnew/core/management/commands/ImportCSV.py',第20行,在 home_team = Team.objects.get_or_create(team_name = row [2])[0],...' – Withnail

1

嘗試home_team = Team.objects.get(team_name=row[2])。問題來自Team.id字段是一個整數字段(因爲沒有定義primary_key字段,django會自動創建一個整數id字段),並且您正在爲其分配字符串。

+0

感謝 - 它稍微移動了一點:該建議完成了該行,然後閱讀下一個錯誤狀態:'core.models.DoesNotExist:團隊匹配查詢不存在。查找參數是{'team_name':'Bristol City'}'。如果我嘗試使用'get_or_create',它會提供'ValueError:Can not assign'(,False)「:」Match.home_team「必須是一個」Team「實例。' – Withnail

+1

這是因爲'get_or_create'返回一個元組'(實例,was_created)'其中'was_created'表示是否創建了新的實例。爲了使其工作,請嘗試'home_team,_ = Team.objects.get_or_create(...)'或簡單地'Team.objects.get_or_create(...)[0]'。 –