5

I'm trying to figure out what the following line does exactly - specifically the %%s part?

cursor.execute('INSERT INTO mastertickets (%s, %s) VALUES (%%s, %%s)'%sourcedest, (self.tkt.id, n))

Any good mini-tutorial about string formatting and inserting variables into strings with Python?

3
  • That's a stinky piece of code. Where did you find that? That's something I'd like to avoid. Commented Nov 25, 2008 at 13:51
  • mastertickets plugin for trac Commented Nov 25, 2008 at 14:02
  • oh and out of curiosity... i agree it's not very readable (hence the question ;), but how should one do it instead? Commented Nov 25, 2008 at 14:02

5 Answers 5

7

The %% becomes a single %. This code is essentially doing two levels of string formatting. First the %sourcedest is executed to turn your code essentially into:

cursor.execute('INSERT INTO mastertickets (BLAH, FOO) VALUES (%s, %s)', (self.tkt.id, n))

then the db layer applies the parameters to the slots that are left.

The double-% is needed to get the db's slots passed through the first string formatting operation safely.

Sign up to request clarification or add additional context in comments.

Comments

4

"but how should one do it instead?"

Tough call. The issue is that they are plugging in metadata (specifically column names) on the fly into a SQL statement. I'm not a big fan of this kind of thing. The sourcedest variable has two column names that are going to be updated.

Odds are good that there is only one (or a few few) pairs of column names that are actually used. My preference is to do this.

if situation1:
    stmt= "INSERT INTO mastertickets (this, that) VALUES (?, ?)"
elif situation2:
    stmt= "INSERT INTO mastertickets (foo, bar) VALUES (?, ?)"
else:
    raise Exception( "Bad configuration -- with some explanation" )
cursor.execute( stmt, (self.tkt.id, n) )

When there's more than one valid combination of columns for this kind of thing, it indicates that the data model has merged two entities into a single table, which is a common database design problem. Since you're working with a product and a plug-in, there's not much you can do about the data model issues.

Comments

3

Having the column names inserted using string formatting isn't so bad so long as they aren't user-provided. The values should be query parameters though:

stmt = "INSERT INTO mastertickets (%s, %s) VALUES (?, ?)" % srcdest
...
cursor.execute( stmt, (self.tkt.id, n) )

Comments

1

%% turns into a single %

Comments

0

It does the same:

cursor.execute('INSERT INTO mastertickets (%s, %s) VALUES (:%s, :%s)' % \
    tuple(sourcedest + sourcedest), dict(zip(sourcedest, (self.tkt.id, n))))

Never do that.

1 Comment

oh don't worry. i won't. o_O

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.