How can I convert a sql where clause string to a sqlalchemy query? I'm assuming I already know the table.
I'm building an Angular webapp which hits a Flask API for data. Flask is using sqlalchemy to query the db. jQuery-QueryBuilder fromSQL (http://querybuilder.js.org/plugins.html#import-export) exports filters as raw SQL which I want to pass back to the api, parse, and query.
For example:
where_str = "name LIKE '%BOB%' AND fruit != 'pineapple'"
would get converted to:
session.query(Table).filter(Table.name.like('%BOB%')).filter(Table.fruit != 'pineapple)
Tagging blaze because odo might be what I need.
You can try to execute session.query(Table).filter(where_str). It worked for me on SQLAlchemy v0.5.8.
You can also build the whole SQL statement string and use the Connection.execute() method to execute it. Either way, passing SQL statements as strings directly from the webpage to the application can be very dangerous.
You don't need to filter twice to add an AND you can do this:
session.query(Table).filter(Table.name.like('%BOB%'), Table.fruit != 'pineapple)
Related
Is there an SQL query builder (in Python) which allows me to "parse" and initial SQL query, add certain operators and then get the resulting SQL text?
My use case is the following:
Start with a query like: "SELECT * from my_table"
I want to be able to do something like query_object = Query.parse("SELECT * from my_table to get a query object I can manipulate and then write something like query_object.where('column < 10').limit(10) or similar (columns and operators could also be part of the library, may also have to consider existing WHERE clauses)
And finally getting the resulting query string str(query_object) with the final modified query.
Is this something that can be achieved with any of the ORMs? I don't need all the database connection to specific DB-engines or object mappings (although having it is not a limitation).
I've seen pypika, which allows to create an SQL query from code, but it doesn't allow one to parse an existing query and continue from there.
I've also seen sqlparse which allows me to parse and SQL query into tokens. But because it does not create a tree, it is non-trivial to add additional elements to am existing statement. (it is close to what I am looking for, if only it created an actual tree)
Pretty new to sqlite3, so bear with me here..
I'd like to have a function to which I can pass the table name, and the values to update.
I initially started with something like this:
def add_to_table(table_name, string):
cursor.execute('INSERT INTO {table} VALUES ({var})'
.format(
table=table_name,
var=string)
)
Which works A-OK, but further reading about sqlite3 suggested that this was a terribly insecure way to go about things. However, using their ? syntax, I'm unable to pass in a name to specify the variable.
I tried adding in a ? in place of the table, but that throws a syntax error.
cursor.execute('INSERT INTO ? VALUES (?)', ('mytable','"Jello, world!"'))
>> >sqlite3.OperationalError: near "?": syntax error
Can the table in an sql statement be passed in safely and dynamically?
Its not the dynamic string substitution per-se thats the problem. Its dynamic string substitution with an user-supplied string thats the big problem because that opens you to SQL-injection attacks. If you are absolutely 100% sure that the tablename is a safe string that you control then splicing it into the SQL query will be safe.
if some_condition():
table_name = 'TABLE_A'
else:
table_name = 'TABLE_B'
cursor.execute('INSERT INTO '+ table_name + 'VALUES (?)', values)
That said, using dynamic SQL like that is certainly a code smell so you should double check to see if you can find a simpler alternative without the dynamically generated SQL strings. Additionally, if you really want dynamic SQL then something like SQLAlchemy might be useful to guarantee that the SQL you generate is well formed.
Composing SQL statements using string manipulation is odd not only because of security implications, but also because strings are "dumb" objects. Using sqlalchemy core (you don't even need the ORM part) is almost like using strings, but each fragment will be a lot smarter and allow for easier composition. Take a look at the sqlalchemy wiki to get a notion of what I'm talking about.
For example, using sqlsoup your code would look like this:
db = SQLSoup('sqlite://yourdatabase')
table = getattr(db, tablename)
table.insert(fieldname='value', otherfield=123)
db.commit()
Another advantage: code is database independent - want to move to oracle? Change the connection string and you are done.
I am trying to update a table from the Snowflake Connector in python to a Snowflake table;
update TABLE set X = 100 where Y = 'Applebee's'
To escape the single quote in the Snowflake UI, I would format the "where" clause to be
where Y = 'Applebee\'s'
Also tried:
where Y = 'Applebee''s'
However, no fix that I have tried is succeeding to workaround this error in python. Is there a way to do this from python, in a one step process, without any steps in Snowflake? I only care about workarounds from python.
In all SQL, the only true way to avoid weird characters and not have to account for each possibility is to parametrized your sql calls either as some sort of stored procedure call or a parametrized call from your client - in this case python.
In general this means, never have a case where you are concatenating a sql string to the value of a where clause like you have above.
Here's an example of how to parametrize a statement in python here
I'm using Django and Python 3.7 along with PostGres 9.5. I have a column in my PostGres table of type text, which records URLs for articles. I want to run a query that compares everything before the query string, e.g.
SELECT * FROM article where regexp_replace(url, '\?.*$', '') = :url_wo_query_info
but I'm not sure how to pull this off in Django. Normally if I want to straigh tup query on just a URL, I could write
Article.objects.filter(url=url)
BUt I'm unsure how to do the above in Django's lingo because there is a more complicated function involved.
You can use Func with F expressions to use database functions on model fields. Your query would look like this in Django ORM:
Article.objects.all().annotate(
processed_url=Func(
F('url'),
Value('\?.*$'), Value(''),
function='regexp_replace',
)
).filter(processed_url=url_wo_query_info)
I've tried the following query with Django,
def search(search_text):
q = Info.objects.filter(title__contains=str(search_text))
print q.query
The query that get printed is
SELECT "d"."id", "d"."foo" FROM "d_info" WHERE "d_info"."title" LIKE %hello% ESCAPE '\'
The query fails because the text after LIKE doesn't have quotes around it. The query succeeds when I run the query on the sql prompt with quotes around the text after LIKE like below
SELECT "d"."id", "d"."foo" FROM "d_info" WHERE "d_info"."title" LIKE '%hello%' ESCAPE '\'
How do I get Django to add the quotes around the search_text so that the query succeeds ?
I'm using Djanog with sqlite3
I tried this out with Postgresql 8.3. The query is generated without quotes. However executing the filter returns a valid queryset with expected instances. Can you try executing
q = Info.objects.filter(title__contains=str(search_text))
print q.count()
and see if it works?
Posting my comment above as the answer
It so turns out the query works within Django, but when asked to print the query and if I copy the query printed and execute it in a mysql shell or sqlite shell, it doesn't work.
Django is probably printing the query wrong