Hi Peter,

Thanks for the response!  Several things you stated definitely got me
thinking.  I really appreciate the response.  I used what you said and I am
able to accomplish what I needed.

Thanks!
Aaron



On Mon, Dec 21, 2015 at 7:23 PM, Peter Otten <__pete...@web.de> wrote:

> Aaron Christensen wrote:
>
> > Hello,
> >
> > I am trying to figure out how to populate a shelve file with a nested
> > dictionary.
> >
> > These are my requirements:
> >
> > -Create shelve file called people.db
> > -Append the shelve file with new people (person_1, person_2, etc.).
> > -Use a for loop to iterate through 'attributes' so that I do not need to
> > write out the lengthy code line by line to populate to the shelve file.
> > -Need to reference shelve file data for future use
> >
> > Here is the key/value format that I would like to append to the shelve
> > file.
> >
> > person_1 = { 'name': 'Bob', 'type': 'employee', 'attributes':
> >         [{'game': 'basketball', 'high score': '100', 'time': '3.34'},
> >         {'game': 'bridge', 'high score': '10', 'time': '30.34'},
> >         {'game': 'foosball', 'high score': '2', 'time': '24'}]
> >         '''
> >         50+ other attributes
> >         '''
> >         }
> >
> > # Example: s['person_1]['attributes'][2]['time'] would call out '24'.
> > # 's' is from 's = shelve.open('people')'
> > I have a dictionary dictPeople.py file (created using pprint() that
> > contains the information of person_1, etc. And I am extracting only a
> > small percentage of the data that is needed.
> >
> > I have tried the following, but I get an invalid key error.
> >
> > import shelve, dictPeople
> > s = shelve.open('people')
> > person = 'person_1'
> > s[person]['name'] = dictPeople.person_1['name']
> > s[person]['type'] = dictPeople.person_1['type']
> > # I need to use this for loop because there are 50+ attributes.
> > for attribute in range(0, len(dictPeople['attributes'][attribute])):
> > s[person]['attributes'][attribute]['game'] = \
> >     dictPeople['attributes'][attribute]['game']
> > s[person]['attributes'][attribute]['high score'] = \
> >     dictPeople['attributes'][attribute]['high score']
> > s[person]['attributes'][attribute]['time'] = \
> >     dictPeople['attributes'][attribute]['time']
> > It turns out, I get the key error because I am not allowed to reference a
> > key/value pair the same way that I can with a dictionary. However, the
> > crazy thing is that I can call values in the db file using the same exact
> > format when trying to write.
> >
> > For example: I can read data from the .db file using:
> >
> > x = s['person_1']['name']
> > print(x)
> > BUT! I cannot write to that .db file using that exact format or I get an
> > invalid key error. Makes no sense!
> >
> > s['person_1']['name'] = 'Bob'
> > # Returns invalid key entry.  Makes no sense.
> > Therefore, I tried to extract data and populate the db file using the
> > following:
> >
> > s[person] = {   'name': dictPeople.person_1['name'],
> >             'type': dictPeople.person_1['type'],
> > for attribute in range(0, len(dictPeople['attributes'][attribute])):
> >     ['game':  dictPeople['attributes'][attribute]['game'],
> >     'high score': dictPeople['attributes'][attribute]['high score'],
> >     'time': dictPeople['attributes'][attribute]['time']]
> >
> > }
> > But, this obvously doesn't work because of the for loop. How can I do
> > this?
> >
> > -I am trying to figure out how to extract data from the dictionary
> > dictPeople.py file and store it in the people.db file.
> > -I am trying to add new people to the people.db file as more people
> become
> > available.
> > -I need to use the for loop because of the 50+ attributes I need to add.
> > -My future steps would be to modify some of the data values that I
> extract
> > and used to populate the people.db file, but my first step is to, at
> > least, extract, and then populate the people.db file.
> >
> > Any help or guidance is greatly appreciated.  Thank you for your time and
> > reading my question.
>
> You don't need these loops. The problem is that when you read the dict from
> the db
>
> db = shelve.open(...)
> person = db["person_1"]
>
> person is a Python object completely independent of the shelve and the
> shelve has no way to trace changes to that object:
>
> $ python3
> Python 3.4.3 (default, Oct 14 2015, 20:28:29)
> [GCC 4.8.4] on linux
> Type "help", "copyright", "credits" or "license" for more information.
> >>> import shelve
> >>> db = shelve.open("tmp.shelve")
> >>> person_1 = { 'name': 'Bob', 'type': 'employee', 'attributes':
> ...         [{'game': 'basketball', 'high score': '100', 'time': '3.34'},
> ...         {'game': 'bridge', 'high score': '10', 'time': '30.34'},
> ...         {'game': 'foosball', 'high score': '2', 'time': '24'}]
> ... }
> >>> db["person_1"] = person_1
> >>> db["person_1"]["age"] = 42
> >>> db.close()
> >>> db = shelve.open("tmp.shelve")
> >>> db["person_1"]
> {'name': 'Bob', 'type': 'employee', 'attributes': [{'time': '3.34', 'high
> score': '100', 'game': 'basketball'}, {'time': '30.34', 'high score': '10',
> 'game': 'bridge'}, {'time': '24', 'high score': '2', 'game': 'foosball'}]}
>
> When you look at the data you see that there is no "age" key. The straight-
> forward fix is to always use an assignment
>
> db[key] = new_value
>
> when you want a change:
>
> >>> person = db["person_1"]
> >>> person["age"] = 42
> >>> db["person_1"] = person
> >>> db.close()
>
> That way the change will survive:
>
> >>> db = shelve.open("tmp.shelve")
> >>> db["person_1"]["age"]
> 42
>
> Alternatively you can open the shelve with writeback=True:
>
> >>> db = shelve.open("tmp.shelve", writeback=True)
> >>> db["person_1"]["height"] = 2.0
> >>> db.close()
> >>> db = shelve.open("tmp.shelve", writeback=True)
> >>> db["person_1"]["height"]
> 2.0
>
> That way every value will be written back (even when you don't modify it)
> and therefore all mutations persist, but you pay for the convenience with
> superfluous caching and writing.
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to