An extension to DBAPI 2.0 for easier SQL queries



Similar documents
A Brief Introduction to MySQL

Advanced Tornado TWENTYONE Advanced Tornado Accessing MySQL from Python LAB

Writing MySQL Scripts With Python's DB-API Interface

Relational Database: Additional Operations on Relations; SQL

SQL Injection. SQL Injection. CSCI 4971 Secure Software Principles. Rensselaer Polytechnic Institute. Spring

A basic create statement for a simple student table would look like the following.

Writing MySQL Scripts with Python DB-API

Services. Relational. Databases & JDBC. Today. Relational. Databases SQL JDBC. Next Time. Services. Relational. Databases & JDBC. Today.

Exposed Database( SQL Server) Error messages Delicious food for Hackers

Serious Threat. Targets for Attack. Characterization of Attack. SQL Injection 4/9/2010 COMP On August 17, 2009, the United States Justice

SnapLogic Salesforce Snap Reference

SQL: Programming. Introduction to Databases CompSci 316 Fall 2014

Retrieving Data Using the SQL SELECT Statement. Copyright 2006, Oracle. All rights reserved.

SQL Simple Queries. Chapter 3.1 V3.0. Napier University Dr Gordon Russell

Triggers & Packages. {INSERT [OR] UPDATE [OR] DELETE}: This specifies the DML operation.

Python and MongoDB. Why?

Programming Database lectures for mathema

Firebird. Embedded SQL Guide for RM/Cobol

Concepts Design Basics Command-line MySQL Security Loophole

Financial Data Access with SQL, Excel & VBA

Websense SQL Queries. David Buyer June 2009

Agenda. SQL Injection Impact in the Real World Attack Scenario (1) CHAPTER 8 SQL Injection

Python Database Application Programming Interface (DB-API)

Virtual Private Database Features in Oracle 10g.

LogLogic General Database Collector for Microsoft SQL Server Log Configuration Guide

The first time through running an Ad Hoc query or Stored Procedure, SQL Server will go through each of the following steps.

IENG2004 Industrial Database and Systems Design. Microsoft Access I. What is Microsoft Access? Architecture of Microsoft Access

Introduction to Server-Side Programming. Charles Liu

Databases for text storage

JavaScript: Introduction to Scripting Pearson Education, Inc. All rights reserved.

Intro to Databases. ACM Webmonkeys 2011

MyOra 3.0. User Guide. SQL Tool for Oracle. Jayam Systems, LLC

Web Application Disassembly with ODBC Error Messages By David Litchfield Director of Security

database abstraction layer database abstraction layers in PHP Lukas Smith BackendMedia

Query-by-Example (QBE)

Chapter 22 Database: SQL, MySQL,

In this Lecture SQL SELECT. Example Tables. SQL SELECT Overview. WHERE Clauses. DISTINCT and ALL SQL SELECT. For more information

Achieving Database Interoperability Across Data Access APIs through SQL Up-leveling

SQL Injection for newbie

SQL - QUICK GUIDE. Allows users to access data in relational database management systems.

Exercise 4 Learning Python language fundamentals

B.1 Database Design and Definition

Spring Data JDBC Extensions Reference Documentation

CS 145: NoSQL Activity Stanford University, Fall 2015 A Quick Introdution to Redis

How Strings are Stored. Searching Text. Setting. ANSI_PADDING Setting

Maintaining Stored Procedures in Database Application

A table is a collection of related data entries and it consists of columns and rows.

Cassandra A Decentralized, Structured Storage System

SQL is capable in manipulating relational data SQL is not good for many other tasks

Information Systems (Informationssysteme)

Introduction To Hive

Rapid Application Development of Oracle Web Systems

CSSEA Helpdesk User Guide

HTSQL is a comprehensive navigational query language for relational databases.

Below is a table called raw_search_log containing details of search queries. user_id INTEGER ID of the user that made the search.

2874CD1EssentialSQL.qxd 6/25/01 3:06 PM Page 1 Essential SQL Copyright 2001 SYBEX, Inc., Alameda, CA

SQL Basics for RPG Developers

SQL Server Database Coding Standards and Guidelines

Moving Enterprise Applications into VoiceXML. May 2002

SAP InfiniteInsight Explorer Analytical Data Management v7.0

Darshan Institute of Engineering & Technology PL_SQL

Micro Focus Database Connectors

In This Lecture. Physical Design. RAID Arrays. RAID Level 0. RAID Level 1. Physical DB Issues, Indexes, Query Optimisation. Physical DB Issues

White Paper. Blindfolded SQL Injection

PTC Mathcad Prime 3.0 Keyboard Shortcuts

Cloud Powered Mobile Apps with Azure

In This Lecture. SQL Data Definition SQL SQL. Notes. Non-Procedural Programming. Database Systems Lecture 5 Natasha Alechina

Best Practices for Dynamic SQL

InterBase 6. Embedded SQL Guide. Borland/INPRISE. 100 Enterprise Way, Scotts Valley, CA

Relational databases and SQL

Topics. Query Repo Model Changeset

SQL Injection Attack Lab Using Collabtive

How To Use The Correlog With The Cpl Powerpoint Powerpoint Cpl.Org Powerpoint.Org (Powerpoint) Powerpoint (Powerplst) And Powerpoint 2 (Powerstation) (Powerpoints) (Operations

Chapter 9 Java and SQL. Wang Yang wyang@njnet.edu.cn

Chapter 9, More SQL: Assertions, Views, and Programming Techniques

Porting from Oracle to PostgreSQL

MyOra 3.5. User Guide. SQL Tool for Oracle. Kris Murthy

Django MSSQL Documentation

shodan-python Documentation

Information Systems SQL. Nikolaj Popov

Using Temporary Tables to Improve Performance for SQL Data Services

SQL Injection Attack Lab

PROJECT REPORT OF BUILDING COURSE MANAGEMENT SYSTEM BY DJANGO FRAMEWORK

How To Use Query Console

Automating SQL Injection Exploits

Lab 9 Access PreLab Copy the prelab folder, Lab09 PreLab9_Access_intro

SQL. Short introduction

College Tuition: Data mining and analysis

Apache Cassandra Query Language (CQL)

Database Query 1: SQL Basics

MPP Manager Users Guide

dbext for Vim David Fishburn h5p://

CS106A, Stanford Handout #38. Strings and Chars

PostgreSQL Audit Extension User Guide Version 1.0beta. Open Source PostgreSQL Audit Logging

Transcription:

An extension to DBAPI 2.0 for easier SQL queries Martin Blais EWT LLC / Madison Tyler http://furius.ca/antiorm/

Introduction connection = dbapi.connect(...) cursor = connection.cursor() SELECT * FROM Users WHERE username = raymond """)

Escaping Values name = raymond SELECT * FROM Users WHERE username = %s """, (name,)) A common mistake is to forget to call with a tuple or a dict: SELECT * FROM Users WHERE username = %s """, name) <--- this fails

Escaping Values name = raymond SELECT * FROM Users WHERE username = %s """, (name,)) A common mistake is to forget to call with a tuple or a dict: SELECT * FROM Users WHERE username = %s """, name) <--- this fails

String Interpolation Pitfalls Another mistake is to use string interpolation: SELECT * FROM Users WHERE username = %s """ % name) ERROR! The resulting query is missing the quotes around the values: SELECT * FROM Users WHERE username = raymond

String Interpolation Pitfalls And you cannot fix this by hand: SELECT * FROM Users WHERE username = %s """ % name) ERROR! The resulting query is missing the quotes around the values: SELECT * FROM Users WHERE username = ray s cat

String Interpolation Pitfalls Using repr() will not help either: SELECT * FROM Users WHERE username = %s """ % repr(name)) ERROR! Escaping syntax is database-specific: SELECT * FROM Users WHERE username = ray s cat

DBAPI Must Escape Values You absolutely must let DBAPI deal with the escaping of values. The escaping syntax for string constants * timestamps dates blobs (other SQL data types?) depends on the database backend.

Non-escaped Substitutions What if you need to format non-escaped variables? SELECT email, phone FROM Users WHERE username = raymond SELECT %s, %s FROM Users WHERE username = %s """, (col1, col2, name)) <--- will not work

Non-escaped Substitutions What if you need to format non-escaped variables? SELECT email, phone FROM Users WHERE username = raymond SELECT %s, %s FROM Users WHERE username = %%s """ % (col1, col2), (name,)) <-- two steps! Because of the string interpolation step, you have to use %%s for the escaped values Specifying the parameters in the right order becomes tricky

Lists and format-specifiers Sometimes you want to render variable-length lists: INSERT INTO Users (%s, %s) VALUES (%%s, %%s) """ % ("email", "phone"), values) INSERT INTO Users (%s, %s, %s) VALUES (%%s, %%s, %%s) """ % ("email", "phone", "address"), values)

Lists and format-specifiers Sometimes you want to render variable-length lists: INSERT INTO Users (%s, %s) VALUES (%%s, %%s) """ % ("email", "phone"), values) INSERT INTO Users (%s, %s, %s) VALUES (%%s, %%s, %%s) """ % ("email", "phone", "address"), values)

Lists and format-specifiers INSERT INTO Users (%s) VALUES (%s) """ % (,.join(columns),,.join(["%%s"] * 2)), values)

And in the real world it gets uglier... When you write real-world queries (instead of Mickey-mouse example queries), it gets even messier: SELECT %s FROM %s WHERE %s > %%s AND %s < %%s LIMIT %s %s """ % (,.join(columns), "Users", "age", "age", 10, "DESC"), (18, 60)) DBAPI s Cursor.execute() method interface is inconvenient to use!

My Proposed Solution: dbapiext Provide a very simple extension that gets rid of the pitfalls of execute() Make it much easier to write queries A single pure Python module, no changes to your DBAPI Support a number of DBAPI implementations No external dependencies Your code dbapiext DBAPI (MySQLdb, psycopg2,...)

New format specifier (%X) We provide a replacement for execute(), and we introduce a new format specifier for escaped arguments: %X (capital X) cursor.execute_f( "INSERT INTO Users (username) VALUES (%X)", name) You can now mix vanilla and escaped values in the arguments, and you are not forced to use a tuple anymore: cursor.execute_f( "INSERT INTO Users (%s) VALUES (%X)", "username", name)

Lists are Recognized and Understood Lists are automatically joined with commas: columns = ["username", "email", "age"] cursor.execute_f(""" INSERT INTO Users (%s) VALUES (...) """, columns,...) INSERT INTO Users (username, email, age) VALUES (...)

Lists are Recognized and Understood This also works for escaped arguments: values = ["Warren", "w@b.com", 76] cursor.execute_f(""" INSERT INTO Users (%s) VALUES (%X) """, columns, values) INSERT INTO Users (username, email, age) VALUES ( Warren, w@b.com, 76) Values are escaped individually and then comma-joined

Dictionaries are Recognized and Understood Dictionaries are rendered as required for UPDATE statements: Comma-separated <name> = <value> pairs Values are escaped automatically UPDATE Lang SET country = brazil, language = portuguese WHERE id = 3 userid = 3 values = {"country": "brazil", "language": "portuguese"} cursor.execute_f(""" UPDATE Lang SET %X WHERE id = %X """, values, userid) (Suggestion by D. Mertz)

Keywords Arguments are Supported cursor.execute_f(""" SELECT %(table)s FROM %s WHERE id = %(id)x """, column_names, table=tablename, id=42) Provide a useful way to recycle arguments (i.e. a table or column name that occurs multiple times) Positional and keyword arguments can be used simultaneously

Performance and Remarks The extension massages your query in a form that can be digested by DBAPI s Cursor.execute() We cache as much of the preprocessing as possible (similar to re, struct) You can cache your queries at load time with qcompile(). I lied in my examples, you have to use it like this (if monkey-patching Cursor fails): execute_f(cursor, """...

Performance and Remarks The extension massages your query in a form that can be digested by DBAPI s Cursor.execute() We cache as much of the preprocessing as possible (similar to re, struct) You can cache your queries at load time with qcompile(). I lied in my examples, you have to use it like this (if monkey-patching Cursor fails): execute_f(cursor, """...

Final Thoughts Ideally, we would want to automatically parse the SQL queries and determine which arguments should be quoted A lot more work Would have to be done at load time for performance reasons

Questions dbapiext is part of a package named antiorm antiorm homepage: http://furius.ca/antiorm/ Questions?