Search code examples
pythongoogle-app-enginelistdatastore

How to update a datastore ListProperty entity adding new elements (without replacing the olds)?


I have this class:

class Contract(db.Model):
    book_number = db.IntegerProperty(required = True)
    initial_page = db.IntegerProperty(required = True)
    final_page = db.IntegerProperty(required = True)
    contract_type = db.StringProperty(required = True)
    parties = db.ListProperty(int)
    date = db.DateTimeProperty (required = True, auto_now = True, auto_now_add = True)

class ContractingParty(db.Model):
    person = db.ReferenceProperty(Person, required=True, collection_name="party_to_contracts")
    contract = db.ReferenceProperty(Contract, required=True)
    condition = db.StringProperty()

I use this code to create an entity named Contract which parties property is an empty list:

    parties = []
    contract_record = Contract(book_number = int(numBook),
                               initial_page = int(numInitialPage),
                               final_page = int(numFinalPage),
                               contract_type = choosed_contract_type,
                               parties = parties)
    contract_record.put()

But I have to populate the parties property with IDs of ContractingPerson entitty. So, in other part of the code, I uptade the parties property of Contract entity, this way:

contracting_party_record = ContractingParty(person = person_key,
                                                      contract = contract_key,
                                                      condition = get_condition)
contracting_party_record.put()
contracting_party_id = contracting_party_record.key().id()
contract = Contract.get_by_id(contract_id)
contract.parties.append(contracting_party_id)
#contract.parties.extend(contracting_party_id)
contract.put()

But when I query datastore, this way:

parties = db.GqlQuery("SELECT * FROM ContractingParty WHERE contract =:c_key", c_key = contract_key).fetch(20)

I got only the last ContractingParty entity I've create. It seems that contract.parties.append(contracting_party_id) is replacing the old list with the new one. Then, I tried to use contract.parties.extend(contracting_party_id). But, now, I got this error:

File "C:\Users\Py\Desktop\contract\main.py", line 363, in post
    contract.parties.extend(contracting_party_id)
TypeError: 'long' object is not iterable

How to fix that?


Solution

  • appending items on the list like contract.parties.append(contracting_party_id) does not replace the previous list it shouldn't do it in your case too.

    what you want to do is using append instead of extend.

    while extend expects an iterable like another list, append adds an item to the list.

    >>> l = [1,2,3]
    >>> l.append(4)
    >>> l
    [1, 2, 3, 4] 
    
    >>> l = [1,2,3]
    >>> l.extend([4,5,6])
    >>> l
    [1, 2, 3, 4, 5, 6]
    >>> 
    

    here the docs: http://docs.python.org/tutorial/datastructures.html