Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy error when adding parameter to string SQL query

I'm trying to compose a string SQL query using SQLALchemy 1.1.2. I followed the explanation from the docs about using textual SQL but encountered a syntax error when I ran the following code:

from sqlalchemy.sql import text

# Create a database connection called "connection"...

q = text('USE :name')
connection.execute(q, name='DATABASE_NAME')

Here's the error message:

"You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to use 
near ''DATABASE_NAME'' at line 1") [SQL: u'USE %s;'] [parameters: 
(u'DATABASE_NAME',)]

Since I'm using the named colon format and passing the parameters as arguments to connection.execute I can't figure out why this problem is arising. I'm using a MySQL server, but if I read the docs correctly the text method should be DB-agnostic.

Thanks in advance for the help.

like image 315
Jonathan Cox Avatar asked Oct 25 '16 20:10

Jonathan Cox


People also ask

What is IntegrityError SQLAlchemy?

IntegrityError is a class within the sqlalchemy. exc module of the SQLAlchemy project.

What is the difference between SQLAlchemy core and ORM?

Choosing Between SQLAlchemy Core and ORM The two modes use slightly different syntax, but the biggest difference between Core and ORM is the view of data as schema or business objects. SQLAlchemy Core has a schema-centric view, which like traditional SQL is focused around tables, keys, and index structures.

Is SQLAlchemy text safe?

The python package SQLAlchemy was scanned for known vulnerabilities and missing license, and no issues were found. Thus the package was deemed as safe to use.


1 Answers

According to the documentation you need to use the bindparams like so:

q = text('USE :name')
q.bindparams(name="DATABASE_NAME")
connection.execute(q)

or like this:

q = text('USE :name')
q = q.bindparams(bindparam("name", String))

connection.execute(q, {"name": "DATABASE_NAME"})

This worked for me with no issues. Edit: I was wrong, it didn't work.

The problem is the bind params is going to auto wrap your value with a single quote. So what's happening is you get the final compiles statement (which is invalid syntax):

use 'DATABASE_NAME'

If you were to create the query: "Select * from mytable where column_a=:name"; this will work. Because it's wrapping the value with single quotes.

I would suggest for your use statement to do:

q = "USE {}".format("DATABASE_NAME") 

Or something similar.

like image 137
CodeLikeBeaker Avatar answered Sep 27 '22 16:09

CodeLikeBeaker