update_or_create为以10为底的int()导致无效的文字:

时间:2019-08-08 07:40:08

标签: python django

我编写了以下代码:

def parse_match_data(self, match_data, statistics_data):
        data = {"all_advanced_fields_populated": True}
        if(match_data["match_hometeam_halftime_score"] == "" or match_data["match_hometeam_halftime_score"] == ""):
            data["all_fields_populated"] = False
            data["home_fh_goals"] = 0
            data["home_sh_goals"] = 0
            data["away_fh_goals"] = 0
            data["away_sh_goals"] = 0
        else:
            data["all_fields_populated"] = True
            data["home_sh_goals"] = 0 if int(match_data["match_hometeam_score"]) - int(match_data["match_hometeam_halftime_score"]) < 0 else int(match_data["match_hometeam_score"]) - int(match_data["match_hometeam_halftime_score"])
            data["away_sh_goals"] = 0 if int(match_data["match_awayteam_score"]) - int(match_data["match_awayteam_halftime_score"]) < 0 else int(match_data["match_awayteam_score"]) - int(match_data["match_awayteam_halftime_score"])
            data["home_fh_goals"] = int(match_data["match_hometeam_halftime_score"])
            data["away_fh_goals"] = int(match_data["match_awayteam_halftime_score"])  

        required_keys = ["Ball Possession", "Goal Attempts", "Shots on Goal"]
        if(statistics_data):
            for statistic in statistics_data:
                if(statistic["type"] in required_keys):
                    data["home_" + statistic["type"].lower().replace(" ", "_")] = statistic["home"].strip('%')
                    data["away_" + statistic["type"].lower().replace(" ", "_")] = statistic["away"].strip('%')

        for key in required_keys:
            if("home_" + key.lower().replace(" ", "_") not in data):
                data["home_" + key.lower().replace(" ", "_")] = 0
                data["all_advanced_fields_populated"] = False
            if("away_" + key.lower().replace(" ", "_") not in data):
                data["away_" + key.lower().replace(" ", "_")] = 0
                data["all_advanced_fields_populated"] = False

        return data

    def statistics(self, match, fixtures, type):
        for fixture in fixtures:
            existing_fixture = Fixture.objects.filter(external_id=fixture["match_id"])
            if(not existing_fixture.exists() or (existing_fixture.exists() and existing_fixture.first().total_goals == 0)):
                home_id = fixture["match_hometeam_id"]
                away_id = fixture["match_awayteam_id"]
                league_id = fixture["league_id"]
                country_id = fixture["country_id"]
                date = fixture["match_date"] + " " + fixture["match_time"]
                home_name = fixture["match_hometeam_name"].split(" (")[0]
                away_name = fixture["match_awayteam_name"].split(" (")[0]
                league_name = fixture["league_name"]
                country_name = fixture["country_name"]

                url = "https://apiv2.apifootball.com/?action=get_statistics&match_id={}&APIkey={}".format(fixture["match_id"], self.key)
                fixture_statistics = json.loads(requests.get(url).content)[fixture['match_id']]['statistics']

                country = Country.create(name=country_name)
                league = League.create(name=league_name, country=country)

                home_data = json.loads(requests.get("https://apiv2.apifootball.com/?action=get_teams&team_id={}&APIkey={}".format(home_id, self.key)).content)
                away_data = json.loads(requests.get("https://apiv2.apifootball.com/?action=get_teams&team_id={}&APIkey={}".format(away_id, self.key)).content)

                home = Team.create(name=home_name, league=league, external_id=home_id, image_url=home_data[0]["team_badge"])
                away = Team.create(name=away_name, league=league, external_id=away_id, image_url=away_data[0]["team_badge"])

                parsed_match_data = self.parse_match_data(fixture, fixture_statistics)

                home_sh_goals = parsed_match_data["home_sh_goals"]
                away_sh_goals = parsed_match_data["away_sh_goals"]

                related_fixture, created = Fixture.objects.filter(external_id=fixture["match_id"]).update_or_create(external_id=fixture["match_id"], home=home, away=away, date=date, league=league, total_goals=fixture["match_awayteam_score"] + fixture["match_hometeam_score"],
                            total_away_goals=fixture["match_awayteam_score"], total_home_goals=fixture["match_hometeam_score"], total_fh_goals=(parsed_match_data["home_fh_goals"] + parsed_match_data["away_fh_goals"]),
                            total_sh_goals=home_sh_goals + away_sh_goals, total_home_fh_goals=parsed_match_data["home_fh_goals"], total_home_sh_goals=home_sh_goals,
                            total_away_sh_goals=away_sh_goals, total_away_fh_goals=parsed_match_data["away_fh_goals"], no_default_values=parsed_match_data["all_fields_populated"], total_attempts_home=parsed_match_data["home_goal_attempts"], total_attempts_away=parsed_match_data["away_goal_attempts"],
                            total_shots_ot_home=parsed_match_data["home_shots_on_goal"], total_shots_ot_away=parsed_match_data["away_shots_on_goal"], total_possession_home=parsed_match_data["home_ball_possession"], total_possession_away=parsed_match_data["away_ball_possession"],
                            no_advanced_default_values=parsed_match_data["all_advanced_fields_populated"])
                # print(related_fixture)

                Related.objects.create(sort=type, from_fixture=match, to_fixture=related_fixture)
            else:
                Related.objects.create(sort=type, from_fixture=match, to_fixture=existing_fixture.first())

在统计方法中使用update_or_create函数的“创建”部分时似乎很好,但是当它需要“更新”项目时会引发以下错误:

Traceback (most recent call last):
  File "manage.py", line 25, in <module>
    main()
  File "manage.py", line 21, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.7/dist-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.7/dist-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.7/dist-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.7/dist-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/root/Documents/projects/football/sbbetting/management/commands/api-schedule.py", line 150, in handle
    self.analyze(fixture)
  File "/root/Documents/projects/football/sbbetting/management/commands/api-schedule.py", line 138, in analyze
    self.statistics(match, home_fixtures, "Home Overal")
  File "/root/Documents/projects/football/sbbetting/management/commands/api-schedule.py", line 92, in statistics
    no_advanced_default_values=parsed_match_data["all_advanced_fields_populated"])
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/query.py", line 554, in update_or_create
    obj = self.select_for_update().get(**kwargs)
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/query.py", line 399, in get
    clone = self.filter(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/query.py", line 892, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/query.py", line 910, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/sql/query.py", line 1290, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/sql/query.py", line 1318, in _add_q
    split_subq=split_subq, simple_col=simple_col,
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/sql/query.py", line 1251, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/sql/query.py", line 1116, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/lookups.py", line 20, in __init__
    self.rhs = self.get_prep_lookup()
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/lookups.py", line 70, in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "/usr/local/lib/python3.7/dist-packages/django/db/models/fields/__init__.py", line 1819, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: ''

我了解到在创建模型时使用“空白”可能会导致此问题,但我在模型代码中未使用“空白”:

class Fixture(models.Model):
    external_id = models.CharField(max_length=200)

    home = models.ForeignKey(Team, on_delete=models.CASCADE, related_name="home")
    away = models.ForeignKey(Team, on_delete=models.CASCADE, related_name="away")

    league = models.ForeignKey(League, on_delete=models.CASCADE)

    date = models.DateTimeField()

    related_fixtures = models.ManyToManyField('self', blank=True, symmetrical=False, through='Related')

    total_goals = models.IntegerField(default=0)

    total_fh_goals = models.IntegerField(default=0)
    total_sh_goals = models.IntegerField(default=0)

    total_home_goals = models.IntegerField(default=0)
    total_away_goals = models.IntegerField(default=0)

    total_home_fh_goals = models.IntegerField(default=0)
    total_home_sh_goals = models.IntegerField(default=0)

    total_away_fh_goals = models.IntegerField(default=0)
    total_away_sh_goals = models.IntegerField(default=0)

    total_attempts_home = models.IntegerField(default=0)
    total_attempts_away = models.IntegerField(default=0)

    total_shots_ot_home = models.IntegerField(default=0)
    total_shots_ot_away = models.IntegerField(default=0)

    total_possession_home = models.IntegerField(default=0)
    total_possession_away = models.IntegerField(default=0)

    no_default_values = models.BooleanField(default=False)
    no_advanced_default_values = models.BooleanField(default=False)

    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

1 个答案:

答案 0 :(得分:1)

错误ValueError: invalid literal for int() with base 10: ''显然意味着您正在尝试用空值=>''填充一个必填字段(可以是FK)。因此,该字段不是必需字段,可以为空,然后必须在其定义中添加blank=True, null=True

your_field = models.IntegerField(default=0, blank=True, null=True)
your_FK_field  = models.ForeignKey(TheOtherModel, blank=True, null=True)

或此字段为必填字段,并且必须具有整数值,在这种情况下,您必须确保该值是有效的Integer。

在两种情况下,最好将以下值打印出来以查看哪个值为空:

        home_id = fixture["match_hometeam_id"]
        away_id = fixture["match_awayteam_id"]
        league_id = fixture["league_id"]
        country_id = fixture["country_id"]
        date = fixture["match_date"] + " " + fixture["match_time"]
        home_name = fixture["match_hometeam_name"].split(" (")[0]
        away_name = fixture["match_awayteam_name"].split(" (")[0]
        league_name = fixture["league_name"]
        country_name = fixture["country_name"]