Frozease
Frozease

Reputation: 33

Change information in a sqlite3 table using keyword arguments as a function input, how can I do this in Python?

The keyword arguments are idx, name and passwd. to update the record with index 3 to the name ’Brian’, the method is called as update(idx=3, name=’Brian’). The method returns False if the parameter idx is absent. also the password may be present and the record with the index is updated with the given values for the fields.

I've tried something like this, but get a str object not callable error, I've attempted to look at other scripts here, but I keep getting errors.

def update(self, **kwargs):
    ''' keyword arguments are idx, name and password.
     For example, to update the record with index 3 to
     the name ’Brian’, the method is called as
     update(idx=3, name=’Brian’). The method returns
     False if the parameter idx is absent. In addition
     to name, also the passwd may be present and the record
     with the index is updated with the given values
     for the fields. The method update returns True if the
     updates succeeded, or False otherwise.'''

    if 'idx' in kwargs:

        query = 'UPDATE players set name = ?, password = ? WHERE idx = ?' (kwargs['name'], kwargs['password'],kwargs['idx'])

        self.cr.execute(query)

        self.db.commit()

        print('records updated')

        return True

    else:

        print('records failed to update')

        return False

Upvotes: 2

Views: 558

Answers (1)

kindall
kindall

Reputation: 184221

You can't put the argument with the query like you've done:

query = 'UPDATE players set name = ?, password = ? WHERE idx = ?' (kwargs['name'], kwargs['password'],kwargs['idx'])

Python will think you're trying to call that string literal like it was a function.

Instead, pass the args when you execute the query, because the execute() method is what actually stuffs your values into the SQL statement.

query = 'UPDATE players set name = ?, password = ? WHERE idx = ?'
self.cr.execute(query, (kwargs['name'], kwargs['password'], kwargs['idx']))

A better approach is to use named placeholders; then you can just pass in kwargs instead of having to dig out the fields you want:

query = 'UPDATE players set name = :name, password = :password WHERE idx = :idx'
self.cr.execute(query, kwargs)

To answer the question from your comment, you can dynamically create the query based on the fields for which you have values by iterating over the dictionary:

assert "idx" in kwargs   # idx is a required field
query = "UPDATE players SET"
for field in kwargs:
    if field != "idx":
        query += " {f} = :{f},".format(f=field)
query = query.strip(",")   # strip off unneeded comma after last field
query += " WHERE idx = :idx"
self.cr.execute(query, kwargs)

Or as a single statement:

query = "UPDATE players SET " + ", ".join(f + " = :" + f 
         for f in kwargs if f != "idx") + " WHERE idx = :idx"

Upvotes: 3

Related Questions