Error Trying to Import JSON to Django Database - TypeError: string indices must be integers
Question: I've been self-teaching myself programming for less than a month. I'm trying
to build a Django site to help the process. I've spent the last 3 days
searching for a solution to this problem to no avail.

I stole this code from someone on Github, and it works fine when calling the
JSON URL file for which it was specifically written. But I've been trying to
modify it to work with another JSON URL file and it's not working. It's a
command file that is used to import data into the database. So here's what
happens when I run the command:

    
    
    PS C:\django-1.5.1\dota\mysite> python manage.py update_items
    Fetching item list..
    TypeError: string indices must be integers
    

I apologize if there is too much code below, I really don't know what kinds of
things people would already implicitly know. I'm trying to import the fields
from each game item listed in this JSON file. I'm just starting with 2 fields
to try to get this working.

You can view the JSON file from the URL below, but it is formatted like this:

    
    
    {
    "itemdata": {
        "blink": {
            "id": 1,
            "img": "blink_lg.png",
            "dname": "Blink Dagger",
            "qual": "component",
            "cost": 2150,
            "desc": "Active: Blink - Teleport to a target point up to 1200 units away.  If damage is taken from an enemy hero, Blink Dagger cannot be used for 3 seconds.",
            "attrib": "",
            "mc": 75,
            "cd": 12,
            "lore": "The fabled dagger used by the fastest assassin ever to walk the lands.",
            "components": null,
            "created": false
        },
        "blades_of_attack": {
            "id": 2,
    

And here are the 4 files related to the command file update_items.py:

models.py -- this model defines the database fields

    
    
    from django.db import models
    
    class Item(models.Model):
        unique_id = models.IntegerField(unique=True)
        dname = models.CharField(max_length=255)
    
        def __unicode__(self):
            return self.dname
    

update_items.py -- this is the command file to import the json data into the
database

    
    
    from django.core.management.base import BaseCommand, CommandError
    from django.core.management.base import NoArgsCommand
    from items.utils.api import SteamWrapper
    from items.models import Item
    
    class Command(NoArgsCommand):
    help = 'Fetches and updates the items'
    
    def update_item(self, item):
        try:
            db_item = Item.objects.get(unique_id=item['id'])
            print 'Updating %s..' % item['dname']
        except Item.DoesNotExist:
            print 'Creating %s..' % item['dname']
        db_item = Item()
        db_item.unique_id = item['id']
        db_item.dname = item['dname']
        db_item.save()
        print 'Done.'
    
    def fetch_items(self, result):
            try:
                for item in result['itemdata']:
                self.update_item(item)
            except KeyError:
                print "Error while contacting steam API. Please retry."
    
    def handle(self, *args, **options):
          self.stdout.write('Fetching item list..')
          result = SteamWrapper.get_item_list()
          self.fetch_items(result)
          self.stdout.write('Finished.')
    

api.py -- this is the web api call function thing

    
    
    import requests
    from mysite import settings_local
    
    class   SteamWrapper():
        ''' Steam API wrapper '''
    
    API_KEY = settings_local.STEAM_API_KEY
    
    @classmethod
    def _item_send_request(cls, endpoint, *args, **kwargs):
        params = {'key': cls.API_KEY}
        params.update(kwargs)
        request = requests.get(endpoint, params=params)
        return request.json()
    
    @classmethod
    def get_item_list(cls):
        return cls._item_send_request(settings_local.DOTA2_ITEM_LIST_ENDPOINT)
    

local-settings.py

    
    
    DOTA2_ITEM_LIST_ENDPOINT = 'http://www.dota2.com/jsfeed/itemdata'
    

So any ideas? Thanks so much...


Answer: The problem is here:

    
    
    for item in result['itemdata']
    

itemdata is a _dict_ (of dicts). In Python, iterating through a dict yields
the _keys_ : so `item` there is "blink", "blades_of_attack", and so on, hence
the error.

You don't seem to want the keys at all, so you should iterate through
`result['itemdata'].values()`.

(Note there is an indentation error in `update_item`: the line `db_item =
Item()` should be indented within the `except`, otherwise a new item will
always be created.)

