Autocomplete SQL query in db.execute('') on VScode - python

When writing SQL query in python (Flask, if that's necessary) execute(), is there a setting or extensions that would recognize SQL keywords like SELECT, UPDATE, and suggest them with IntelliSense or the like?
Right now the query is recognized as in the picture and keywords are not being suggested.
SQL query keywords in VScode are not recognized (the whole query is green)

No, because you're just putting in a string into execute() that is later read by SQLAlchemy (which I assume you're using). These aren't actually python keywords which IntelliSense can predict. However, you can use the SQLAlchemy ORM, or the higher level query object, which does not use SQL keywords but python methods to manipulate your database. Using this, you might find that IntelliSense can find the definition/declaration of the SQLAlchemy method and offer the usual pointers and helpers it does.
There are other advantages of using the higher level query class of SQLAlchemy, a significant one being you are less likely to be subject to SQL injections and attacks. Because you are executing raw SQL with the execute() command and simply putting an id from the session in, an attacker could alter the session value and inject harmful SQL into your application.
Anyway, that's beside the point but I thought it was worth letting you know.

Related

How to avoid SQL injection on query

My SQL query construction in python code is:
query = '''
SELECT {return_col}
FROM {table_name}
'''.format(colA, tableA)
When I run Bandit security tool, it says "Possible SQL injection vector through string-based query construction."
How do I avoid it?
Best practices recommend to avoid to dynamically build the query and instead use a parameterized query. But the goal is precisely to avoid what you are doing here: prevent a forged parameter to allow an arbitrary query.
If you know why you allow to query any field on any table, and if the account running the query has only SELECT privilege on the database, then you can ignore the warning: it just says that you could allow requests on any table... what you want to do!
But kindly examine the security implications. In some use cases it may be perfectly fine, in others it could be terrible.

Integrate PyQt with a sql orm library (sqlalchemy, peewee, etc.)

PyQt has some nice features like QSqlTableModel and QSqlRelationalTableModel, however, it doesn't contain ORM functionalities and I hate using raw SQL statements in my program. What is a best way to integrate a SQL ORM library like Sqlalchemy, to PyQt SQL facilities? Currently the only solution I can think of is to build my object models in SqlAlchemy and execute the compiled SQL statements with QSqlDatabase manually. Is there any better way to do this? Are there any ways, say, to build a custom backend/adapter for SqlAlchemy that use QSqlDatabase? Other ORM libraries like Peewee are fine, too.
https://docs.sqlalchemy.org/en/13/core/engines.html?highlight=create_engine#sqlalchemy.create_engine
Create a fake engine using the 'mock' strategy that redirects all compiled sql statements to the QSqlDatabase to execute.
There seems to be a catch: functionalities that require interaction with a real database will not work, like checking if a table exists before creation.
Also this doesn't seem to work with the Session API, any calls to commit() and flush() will cause a NotImplementedError.

Is SQL injection protection built into SQLAlchemy's ORM or Core?

I'm developing an aiohttp server application, and I just saw that apparently it isn't able to use SQLAlchemy's ORM layer. So, I was wondering: if my application will only be able to use SQLAlchemy's core, is it still protected against SQL injection attacks?
My code is the following:
async def add_sensor(db_engine, name):
async with db_engine.acquire() as connection:
query = model.Sensor.__table__.insert().values(name=name)
await connection.execute(query)
A comment on the accepted answer in this related question makes me doubt:
you can still use execute() or other literal data that will NOT be
escaped by SQLAlchemy.
So, with the execute() used in my code, does the above quote mean that my code is unsafe? And in general: is protection against SQL Injection only possible with the SQLAlchemy ORM layer, as with the Core layer you'll end up launching execute()?
in your example above i dont see any variable beeing supplied to the database query. Since there is no user supplied input there is also no Sql Injection possible.
Even if there would be a user supplied value as long as you dont use handwritten sql statements with sqlalchemy and instead use the orm model approach (model.Sensor.__table__.select()) as can be seen in your example you are secure against Sql Injection.
In the end its all about telling sqlalchemy explicitely what columns and tables should be used to select and insert data from/to and keeping that separate from the data that is beeing inserted or selected. Never combine the data string with the query string and always use sqlalchemy orm model objects to describe your query.
Bad way (Sql Injectable):
Session.execute("select * form users where name = %s" % request.GET['name'])
Good way (Not Sql Injectable):
Session.execute(model.users.__table__.select().where(model.users.name == request.GET['name']))

Capturing Sybase Showplan programmatically

I'm using sqlalchemy in python to execute my sql queries. I have prefixed my sql queries with a show plan on. However I am not getting the plan back from my results. Does anyone know if the results for the plan is stored somewhere in some system table or is there some flag that needs to be enabled for sqlalchemy DB API to capture the plan?
Just to re-iterate I'm running against a sybase database
It might be worth trying
set noexec on
... as well to see if a query plan comes back.

Insert statment created by django ORM at bulk_create

I am kind of new to python and django.
I am using bulk_create to insert a lot of rows and as a former DBA I would very much like to see what insert statments are being executed. I know that for querys you can use .query but for insert statments I can't find a command.
Is there something I'm missing or is there no easy way to see it? (A regular print is fine by me.)
The easiest way is to set DEBUG = True and check connection.queries after executing the query. This stores the raw queries and the time each query takes.
from django.db import connection
MyModel.objects.bulk_create(...)
print(connection.queries[-1]['sql'])
There's more information in the docs.
A great tool to make this information easily accessible is the django-debug-toolbar.

Categories