从API上载数据到Postgres DB只是停止而没有错误消息

时间:2019-02-06 11:33:01

标签: django database windows postgresql command-line

当我切换到PostgreSQL之前就开始了奇怪的行为,之前使用过sqllite3,并且没有像这样的问题。刚才从我代码的当前状态重新创建了sqllite3 db。只是关闭了我用于其中一个脚本的JsonFields加载到Postrgre基础。仍然有效。

加载到Postgre只是在随机报告上的随机点停止,没有消息,命令行对Ctrl + K命令没有反应。我检查了Postgre服务器,它一直在运行。当我在命令行中“冻结”到数据库的加载后停止服务时,有时会引发错误,有时则不会,并且什么也没有发生。我需要重新打开命令行。

我尝试录制屏幕视频来说明这种行为。但不幸的是,我的屏幕录制软件无法正常工作。 您可以在下面看到代码,但不确定代码中是否存在问题。也许PostgreSQL设置需要做其他事情吗?在使用Postgre的第一天,我能够完全加载脚本。

有一个屏幕截图,其中显示了它在命令行中的外观示例-https://yadi.sk/i/i_LwZHCf_kYpyg

有一种脚本

import os
import urllib.request as urllib

from django.core.management.base import BaseCommand, CommandError
from django.core.files import File
from django.conf import settings

import requests
from tqdm import tqdm

from players.models import Skater
from players.models import Goalie


URL_PLAYERS = 'http://www.nhl.com/stats/rest/{}'
URL_PLAYERS_PICS = 'https://nhl.bamcontent.com/images/headshots/current/168x168/{}.jpg'
PL_TYPE1 = "goalies"
PL_TYPE2 = "skaters"
REP_TYPE1 = 'goaliesummary'
REP_TYPE2 = 'skatersummary'
REP_TYPE3 = 'realtime'
REP_TYPE4 = 'timeonice'
POSITIONS = ['G', 'D', 'C', 'LW', 'RW', 'L', 'R']
WING = 'W'

COUNTRIES = {
    'RUS': 'Russia',
    'CAN': 'Canada',
    'USA': 'USA',
    'CZE': 'Czech Republic',
    'CSK': 'Czech Republic',
    'CHE': 'Switzerland',
    'SWE': 'Sweden',
    'FIN': 'Finland',
    'DEU': 'Germany',
    'DNK': 'Denmark',
    'AUT': 'Austria',
    'FRA': 'France',
    'ITA': 'Italia',
    'NOR': 'Norway',
    'LVA': 'Latvia',
    'SVN': 'Slovenia',
    'SVK': 'Slovakia',
    'NLD': 'Netherlands',
    'AUS': 'Australia',
    'GBR': 'Great Britain',
    'KAZ': 'Kazachstan',
    'BGR': 'Bulgaria',
    'EST': 'Estonia',
    None: '—',
}

HEIGHT_CONVERT = {
    65: "5' 5\"",
    66: "5' 6\"",
    67: "5' 7\"",
    68: "5' 8\"",
    69: "5' 9\"",
    70: "5' 10\"",
    71: "5' 11\"",
    72: "6' 0\"",
    73: "6' 1\"",
    74: "6' 2\"",
    75: "6' 3\"",
    76: "6' 4\"",
    77: "6' 5\"",
    78: "6' 6\"",
    79: "6' 7\"",
    80: "6' 8\"",
    81: "6' 9\"",
    82: "6' 10\"",
}

POSITIONS = ['G', 'D', 'C', 'LW', 'RW', 'L', 'R']



class Command(BaseCommand):

    def import_player(self, player, index):
        # print(player["playerId"])
        # print(player["playerName"])
        id_ = player["playerId"]
        if player['playerDraftOverallPickNo'] is None:
            player['playerDraftOverallPickNo'] = '—'
            player['playerDraftYear'] = '—'

        if player['playerBirthStateProvince'] is None:
            player['playerBirthStateProvince'] = ''

        if player['playerPositionCode'] in POSITIONS[5:]:
            player['playerPositionCode'] += WING

        defaults = {
            'name': player["playerName"],
            'team_abbr': player['playerTeamsPlayedFor'][-3:],
            'position_abbr': player["playerPositionCode"],
            'height': HEIGHT_CONVERT[player["playerHeight"]],
            'weight': player["playerWeight"],
            'birth_date': player["playerBirthDate"],
            'birth_city': player["playerBirthCity"],
            'birth_state': player["playerBirthStateProvince"],
            'birth_country': COUNTRIES[player["playerBirthCountry"]],
            'nation': COUNTRIES[player["playerNationality"]],
            'draft_year': player["playerDraftYear"],
            'draft_number': player["playerDraftOverallPickNo"],
            'games': player["gamesPlayed"],
        }

        if player["playerPositionCode"] == POSITIONS[0]:
            defaults_g = {
                'wins': player["wins"],
                'losses': player["losses"],
                'ot_losses': player["otLosses"],
                'goals_against_av': player["goalsAgainstAverage"],
                'saves_perc': player["savePctg"],
                'saves': player["saves"],
                'shotouts': player["shutouts"],
            }
            defaults = {**defaults, **defaults_g}
            player_obj, created = Goalie.objects.update_or_create(nhl_id=id_, defaults=defaults)

            if self.pic_missing(player_obj):
                self.upload_pic(player_obj)

        else:
            if index == 1:
                defaults_s = {
                    'goals': player["goals"],
                    'goals_avg': player["goals"] / player["gamesPlayed"],
                    'assists': player["assists"],
                    'assists_avg': player["assists"] / player["gamesPlayed"],
                    'points': player["points"],
                    'points_avg': player["points"] / player["gamesPlayed"],
                    'plus_minus': player["plusMinus"],
                    'plus_minus_avg': player["plusMinus"] / player["gamesPlayed"],
                    'penalty_min': player["penaltyMinutes"],
                    'penalty_min_avg': player["penaltyMinutes"] / player["gamesPlayed"],
                    'shots': player["shots"],
                    'shots_avg': player["shots"] / player["gamesPlayed"],
                    'pp_points': player["ppPoints"],
                    'pp_points_avg': player["ppPoints"] / player["gamesPlayed"],
                    'sh_points': player["shPoints"],
                    'sh_points_avg': player["shPoints"] / player["gamesPlayed"],
                }
                defaults = {**defaults, **defaults_s}
                player_obj, created = Skater.objects.update_or_create(nhl_id=id_, defaults=defaults)

                if self.pic_missing(player_obj):
                    self.upload_pic(player_obj)

            elif index == 2:
                defaults = {
                    'hits': player["hits"],
                    'hits_avg': player["hits"] / player["gamesPlayed"],
                    'blocks': player["blockedShots"],
                    'blocks_avg': player["blockedShots"] / player["gamesPlayed"],
                    'faceoff_wins': player["faceoffsWon"],
                    'faceoff_wins_avg': player["faceoffsWon"] / player["gamesPlayed"],
                }
                player_obj, created = Skater.objects.update_or_create(nhl_id=id_, defaults=defaults)

            elif index == 3:
                defaults = {
                    'time_on_ice': time_from_sec(player["timeOnIcePerGame"]),
                    'time_on_ice_pp': time_from_sec(player["ppTimeOnIcePerGame"]),
                    'time_on_ice_sh': time_from_sec(player["shTimeOnIcePerGame"]),
                }
                player_obj, created = Skater.objects.update_or_create(nhl_id=id_, defaults=defaults)


    def pic_missing(self, player_obj):
        file_name = f'{player_obj.slug}.jpg'
        file_path = os.path.join(settings.MEDIA_ROOT, 'players_pics', file_name)
        # player_obj.image.path != file_path can be unnecessary in production
        return not player_obj.image or player_obj.image.path != file_path or not os.path.isfile(file_path)


    def upload_pic(self, player_obj):
        content = urllib.urlretrieve(URL_PLAYERS_PICS.format(player_obj.nhl_id))
        pic = File(open(content[0], 'rb'))
        name_pattern = f'{player_obj.slug}.jpg'
        player_obj.image.save(name=name_pattern, content=pic)


    def handle(self, *args, **options):
        lst = [[REP_TYPE1, PL_TYPE1], [REP_TYPE2, PL_TYPE2], [REP_TYPE3, PL_TYPE2], [REP_TYPE4, PL_TYPE2]]
        for index, item in enumerate(lst):
            print(f'\n Uploading from {item[0]} report')
            data = players_resp(item[0], item[1]).json()["data"]

            for player in tqdm(data):
                self.import_player(player, index)


def time_from_sec(time):
    min_, sec = divmod(time, 60)
    min_ = int(min_)
    sec = str(int(sec)).zfill(2)
    return f'{min_}:{sec}'.rjust(5, '0')


def players_resp(rep_type, pl_type):
    params = {
        'isAggregate': 'false',
        'reportType': 'season',
        'isGame': 'false',
        'reportName': rep_type,
        'cayenneExp': 'gameTypeId=2 and seasonId=20182019',
    }

    return requests.get(URL_PLAYERS.format(pl_type), params=params)

models.py

from django.db import models
from django.contrib.auth.models import User
from django.contrib.postgres.fields import JSONField
from django.utils.text import slugify
from players.storage import OverwriteStorage


class Player(models.Model):
    name = models.CharField(max_length=128, default='nme')
    nhl_id = models.IntegerField(unique=True, default=25)
    slug = models.SlugField()
    image = models.ImageField(upload_to='players_pics', storage=OverwriteStorage(), max_length=None)
    team_abbr = models.CharField(max_length=128, default='')
    team_name = models.CharField(max_length=128, default='')
    position_abbr = models.CharField(max_length=128, default='')
    position_name = models.CharField(max_length=128, default='')
    height = models.CharField(max_length=128, default='')
    weight = models.IntegerField(default=25)
    birth_date = models.CharField(max_length=128, default='')
    birth_city = models.CharField(max_length=128, default='')
    birth_state = models.CharField(max_length=128, default='')
    birth_country = models.CharField(max_length=128, default='')
    nation = models.CharField(max_length=128, default='')
    draft_year = models.CharField(max_length=128, default='')
    draft_number = models.CharField(max_length=128, default='')
    pl_number = models.IntegerField(null=True, default=25)
    age = models.IntegerField(null=True, default=25)
    roster_status = models.CharField(max_length=128, default='')
    captain = models.BooleanField(default=False)
    alt_captain = models.BooleanField(default=False)
    sbs_stats = JSONField(default=dict)
    career_stats = JSONField(default=dict)
    gamelog_stats = JSONField(default=dict)
    games = models.IntegerField(default=25)

    def __str__(self):
        return f'{self.name}'

    def save(self, *args, **kwargs):
        is_new = self.pk is None
        if is_new:
            self.slug = slugify(self.name)
        super(Player, self).save(*args, **kwargs)

    class Meta:
        abstract = True


class Skater(Player):
    favorite = models.ManyToManyField(User, related_name='favorite_s', blank=True)
    goals = models.IntegerField(default=10)
    goals_avg = models.FloatField(default=10)
    assists = models.IntegerField()
    assists_avg = models.FloatField(default=10)
    points = models.IntegerField()
    points_avg = models.FloatField(default=10)
    plus_minus = models.IntegerField()
    plus_minus_avg = models.FloatField(default=10)
    penalty_min = models.IntegerField()
    penalty_min_avg = models.FloatField(default=10)
    shots = models.IntegerField()
    shots_avg = models.FloatField(default=10)
    hits = models.IntegerField(null=True)
    hits_avg = models.FloatField(default=10, null=True)
    blocks = models.IntegerField(null=True)
    blocks_avg = models.FloatField(default=10, null=True)
    faceoff_wins = models.IntegerField(null=True)
    faceoff_wins_avg = models.FloatField(default=10, null=True)
    pp_points = models.IntegerField()
    pp_points_avg = models.FloatField(default=10)
    sh_points = models.IntegerField()
    sh_points_avg = models.FloatField(default=10)
    time_on_ice = models.CharField(max_length=128, default='')
    time_on_ice_pp = models.CharField(max_length=128, default='')
    time_on_ice_sh = models.CharField(max_length=128, default='')


class Goalie(Player):
    favorite = models.ManyToManyField(User, related_name='favorite_g', blank=True)
    wins = models.IntegerField(default=10)
    losses = models.IntegerField()
    ot_losses = models.IntegerField()
    goals_against_av = models.FloatField()
    saves_perc = models.FloatField()
    saves = models.IntegerField()
    shotouts = models.IntegerField()


class Team(models.Model):
    name = models.CharField(max_length=128, default='')
    nhl_id = models.IntegerField(unique=True, default=25)
    abbr = models.CharField(max_length=128, default='')
    slug = models.SlugField()
    image = models.ImageField(upload_to='teams_logos', storage=OverwriteStorage(), max_length=None)
    arena_name = models.CharField(max_length=128, default='')
    arena_location = models.CharField(max_length=128, default='')
    division = models.CharField(max_length=128, default='')
    conference = models.CharField(max_length=128, default='')
    off_site = models.URLField(max_length=128, default='')
    nhl_debut = models.CharField(max_length=128, default='')

    def __str__(self):
        return f'{self.name}'

    def save(self, *args, **kwargs):
        is_new = self.pk is None
        if is_new:
            self.slug = slugify(self.name)
        super(Team, self).save(*args, **kwargs)

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'nhl_web_app_2',
        'USER': 'postgres',
        'PASSWORD': '***',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

views.py

from itertools import chain

import requests
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404

from . import services
from .models import Skater
from .models import Goalie
from .models import Team


def home(request):
    return render(request, 'players/home.html', {'title': 'Home'})


def about(request):
    return render(request, 'players/about.html', {'title': 'About'})


def players(request):
    user = request.user
    context = {
        'goalies': Goalie.objects.all(),
        'skaters': Skater.objects.all(),
        'favorites_g': user.favorite_g.all(),
        'favorites_s': user.favorite_s.all(),
    }
    return render(request, 'players/players.html', context)


def skaters_averages(request):
    user = request.user
    context = {
        'skaters': Skater.objects.all(),
        'favorites_s': user.favorite_s.all(),
    }
    return render(request, 'players/skaters_averages.html', context)


def search(request):
    if 'q' in request.GET and request.GET['q']:
        q = request.GET['q']
        result_s = Skater.objects.filter(name__icontains=q)
        result_g = Goalie.objects.filter(name__icontains=q)
        result_list = result_s.values_list('name', 'nhl_id', 'slug', 'favorite').union(result_g.values_list('name', 'nhl_id', 'slug', 'favorite'))

        context = {
            'players': result_list,
            'query': q,
        }
        return render(request, 'players/search_results.html', context)
    else:
        return HttpResponse('Please submit a search term.')


def player_detail(request, slug, nhl_id):
    bio = services.season_stats(nhl_id)
    player = services.get_player(nhl_id)
    context = {
        'is_favorite': services.is_favorite(request, nhl_id),
        'player': player,
        'bio': bio,
        'stats': bio['stats'][0]['splits'][0]['stat'],
        'total': services.career_stats(nhl_id),
        'sbs_stats': services.sbs_stats(nhl_id),
        'last_gms': player.gamelog_stats[:5],
        'countries': services.COUNTRIES,
        'team': services.TEAM_ABBR,
    }

    return render(request, 'players/player_detail.html', context)


def player_gamelog(request, slug, nhl_id):

    context = {
        'player': services.get_player(nhl_id),
    }
    return render(request, 'players/player_gamelog.html', context)


def player_favorite(request, slug, nhl_id):
    player = services.get_player(nhl_id)
    if player.favorite.filter(id=request.user.id).exists():
        player.favorite.remove(request.user)
    else:
        player.favorite.add(request.user)
    return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))


def favorites(request):
    user = request.user
    context = {
        'favorites_g': user.favorite_g.all(),
        'favorites_s': user.favorite_s.all(),
    }
    return render(request, 'players/favorites.html', context)


def teams(request):
    context = {
        'teams': Team.objects.all(),
    }
    return render(request, 'players/teams.html', context)


def team_detail(request, slug, team_id):
    user = request.user
    skaters = Skater.objects.filter(team_abbr=services.TEAM_ABBR[team_id])
    context = {
        'goalies': Goalie.objects.filter(team_abbr=services.TEAM_ABBR[team_id]),
        'skaters': [
            {
                'type': 'Defencemen',
                'list': skaters.filter(position_abbr=services.POSITIONS[1]),
                'table_id': 'tab6',
            },
            {
                'type': 'Forwards',
                'list': skaters.filter(position_abbr__in=services.POSITIONS[2:]),
                'table_id': 'tab7',
            }
            ],
        'favorites_g': user.favorite_g.all(),
        'favorites_s': user.favorite_s.all(),
        'team': get_object_or_404(Team, nhl_id=team_id)
    }

    return render(request, 'players/team_detail.html', context)

2 个答案:

答案 0 :(得分:0)

我想这与Json结构中使用的引号或单引号有关。 我不知道django及其工作原理的线索,如果您使用一些postgres json函数可能会很有用。

请提供有关版本以及如何执行查询的更多信息。 尝试使用事务控件(BEGIN,COMMIT,ROLLBACK)以将代码块作为事务执行。

答案 1 :(得分:0)

通过卸载NetWorx解决了该问题。 Windows的带宽监视和数据使用情况报告程序。

偶然发现答案的原因是,当我使用Jupyter Notebook时,相同的NetWorx程序每3小时就为Python造成APPCRASH。 我在此answer 中找到了解决方案。顺便说一下,我正在使用Windows 7。

删除NetWorx Jupyter后,一切正常。然后我意识到,Postgres表现异常可能是相同的原因。由于此时NetWorx尚未真正使用,所以只是偶尔看看流量图(每1-2个月)很有趣。