1

I'm generating SQL statements to be used in updating records in an existing database. I'm using pymssql as my db api. Is there any way to make this code more pythonic?

def update_statement(table, keys:list, data:dict):
    """
    This function takes a table name, the keys for the table, and a dictiary for the record to be updated into the table.
    A string representing the SQL statement to be used in the session is returned.
    :param table: The name of the table to be updated.
    :param keys: The primary key/ keys for the table.
    :param data: A dictionary representing the data that is to be updated against.
    :return: The return value is a string representing the SQL statement to be used in the session.
    """
    h = 'UPDATE {} SET'.format(table)
    # Generate SET Clauase
    for key, value in data.items():
        if key in keys:
            continue
        else:
            c = '{} = {},'.format(key, value)
            h = ' '.join([h, c])
    h = h.strip(',')
    h = ' '.join([h, 'WHERE'])
    # Generate WHERE clause
    for key in keys:
        h = ' '.join([h, '{} = {}'.format(key, data[key])])
        h = ''.join([h, ','])
    h = h.strip(',')
    # Add closing semicolon.
    h = ''.join([h, ';'])
    # Return sql statement
    return h

I was wanting to implement the Template class from the string module, but couldn't figure out a way to be able to pass in an iterable number of variables to a template and add a comma to the end of each iteration (except for the last iteration).

4
  • 1
    Do not process sql statements by writing sql yourself... Commented Jul 24, 2017 at 21:26
  • 1
    If the code is working, and you're worried about how Pythonic it is, I would recommend trying out codereview.stackexchange Commented Jul 24, 2017 at 21:27
  • @WillemVanOnsem I understand that. That is why I'm asking for advice/ guidance. I would like to know the proper, pythonic way to accomplish what I'm trying to do. I understand that it is not safe. Commented Jul 24, 2017 at 21:27
  • @Jasonca1: I would use a tool like SQLAlchemy. It allows quite declarative programming and let you use rows of tables like Python objects. Commented Jul 24, 2017 at 21:31

1 Answer 1

2

First of all it is a bad idea to do this SQL statement generation yourself. You better never pass values yourself to SQL, and you can use tools like SQLAlchemy to build even the statements automatically.

That being said you can do it more pythonic way are the following three statements (that replace the entire function):

h1 = ', '.join('{} = {}'.format(k,v) for k,v in data.items() if k not in keys)
h2 = ', '.join('{} = {}'.format(k,data[k]) for k in keys if k in data)
return 'UPDATE {} SET {} WHERE {}'.format(table,h1,h2)
Sign up to request clarification or add additional context in comments.

3 Comments

Values would be passed via a report generated from another table's records. So no human interaction would ever be made. And for such a small project that I'm wanting to do, I feel like SQLalchemy is a little overkill.
@Jasonca1: this can still result in errors: if you pass a string that contains for instance backquotes, then MySQL will interprete this as escape characters. Making SQL statements yourself can be dangerous, even without a hacker.
@Jasonca1: Furthermore I think most frameworks like SQLAlchemy are more convenient: the processing of converting objects from and to the database is quite transparent. Of course no tool can guarantee to be absolutely safe, but usually popular tools will have been bugfixed more than one a person writes him/herself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.