I'm trying to build a .csv data upload facility which will update two tables in sequence. So, i have my 'person' table which has a one to many relationship with the 'thing' table i.e. one person can own many different things.
What i need to do is get the primary key from a 'person' row after an 'update_or_insert ', this ID will then go into the 'owner_id' for the correseponding row in the 'thing' table.
Any ideas as to how i can do this? Excuse my programming i'm a beginner!
model
db.define_table('person',
Field('name'),
Field('age'),
Field('country'),
format='%(name)s')
db.define_table('thing',
Field('thing_name'),
Field('value'),
Field('location'),
Field('owner_id'))
controller
import csv
def importer():
form = FORM(INPUT(_type='submit',_class="btn btn-primary"))
if form.process().accepted:
with open('C:/Users/matt/PycharmProjects/all_projects/web2py/applications/uploadTest/private/test.csv') as csvfile:
readCSV = csv.reader(csvfile, delimiter=',')
next(readCSV, None)
for row in readCSV:
name = row[0]
age = row[1]
country = row[2]
thing_name = row[3]
value = row[4]
location = row[5]
db.person.update_or_insert(name=name,age=age, country=country)
db.thing.insert(thing_name=thing_name,value=value,location=location)
return dict(form=form)
and the following data
person.name,person.age,person.country,thing.name,thing.value,thing.location
matt,38,uk,teddy,12,house
matt,38,uk,kite,13,outside
matt,38,uk,screen,14,shed
matt,38,uk,teddy,15,garden
will,24,us,table,16,house
will,24,us,teddy,17,outside
will,24,us,kite,18,shed
will,24,us,screen,19,garden
pete,56,bel,teddy,20,house
pete,56,bel,table,21,outside
pete,56,bel,teddy,22,shed
pete,56,bel,kite,23,garden
pete,56,bel,screen,24,house
pete,56,bel,teddy,25,outside
matt,38,aus,teddy,26,shed
matt,38,can,kite,27,garden
matt,38,fr,screen,23,shed
pete,25,bel,teddy,22,shed
pete,25,bel,screen,74,shed
ps - i'm getting the file locally as i havent worked out the .retrieve: method yet
.update_or_insert
will not return the record ID in case of update, so you cannot use that method. Instead, simply check for and fetch the record to get its ID. For example:
for row in readCSV:
person = dict(zip(('name', 'age', 'country'), row[:3]))
record = db.person(**person) # Check for a match.
person_id = record.id if record else db.person.insert(**person)
thing = dict(zip('thing_name', 'value', 'location'), row[3:6])
db.thing.insert(owner_id=person_id, **thing)
Note, the db.person(**person)
syntax returns the first record that matches all the values in the person
dictionary (presumably you are expecting at most one match given your data) or None
if there is no match (see the documentation for details).
Also, note that in case there is a matching db.person
record, there is no need to update it, as all the fields you have available in the CSV file are already being used to find the match (i.e., there are no additional fields whose values need to be updated).