0

As far as I know all databases/access libraries have support for preparing statements and binding variables (e.g. PostgreSQL, ODBC, MySQL, etc.). The Python DB-API seems to imply that database libraries should be implemented using bound variables internally, yet the two I've checked does not..?

MySQLdb uses string inerpolation internally (from the implementation of cursor.execute(..)):

query = query % tuple([db.literal(item) for item in args])

and the _mysql.c implementation uses:

r = mysql_real_query(&(self->connection), query, len);

instead of the mysql_stmt_* functions.

In the psycopg2 library all execute paths seem to end up in _psyco_curs_execute, which calls _psyco_curs_merge_query_args, which merges "together a query string and its arguments." (cf. code).

Bound parameters are supposed to be both faster and more secure, so why do these libraries do string formatting instead? Since most queries will be unique, the query/statement caches will be of little use, should I dramatically reduce their sizes (to prevent the cache-maintenance overhead)?

2
  • I don't see where it is stated that it should be implemented via prepared statements. Commented Oct 3, 2015 at 18:09
  • I said "seems to imply", based on this paragraph: "A reference to the operation will be retained by the cursor. If the same operation object is passed in again, then the cursor can optimize its behavior. This is most effective for algorithms where the same operation is used, but different parameters are bound to it (many times)." Are you saying that the DB API is saying that it shouldn't be implemented with bound parameters? Commented Oct 3, 2015 at 18:11

1 Answer 1

1

The overhead of prepared statements overhead is relative small in Postgres. This cache is not shared between processes, it is only per process - so the implementation is pretty simple. So this should not be a argument for any decision. There are others:

  1. blind optimization (or semi blind optimization for >= 9.3)
  2. little bit higher overhead of protocol
  3. but it is 100% safe against SQL injection

Now, almost all interfaces ensure safe client side prepared statements - and it is probably better choose in almost all cases. The exceptions are pretty repeated statements - usually some INSERTs or UPDATEs.

The check what method is used is simple - you can log all queries on PostgreSQL side by set log_mi_duration_statement = 0 and you will see in postgresql.log queries with or without bind parameters (placeholders).

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

Comments

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.