is there a difference between `quote_ident()` and parametized queries in psycopg2? - python-3.x

In python3 and postgresql12, is there a safety difference between parametizing SQL queries the "proper" way or just escaping potentially dangerous content using psycopg2.quote_ident()?
For example, consider these two options.
Option 1:
name = get_unsafe_input_from_web_form()
cursor.execute("SELECT * FROM students WHERE name = %s;", (name,))
Option 2:
from psycopg2.extensions import quote_ident
name = get_unsafe_input_from_web_form()
cursor.execute(f"SELECT * FROM students WHERE name = {quote_ident(name, cursor)};"
The documentation is not particularly explicit. Is Option 2 totally equivalent in terms of safety against injection attacks?

quote_ident() would be the wrong thing to use, as it is for identifiers e.g table, column names. You would want quote_literal() which does not exist in psycopg2.extensions. I would stick with the first option, but using the psycopg2.sql module:
https://www.psycopg.org/docs/sql.html

Safety-wise, both parameterized queries and quote_ident can safely handle untrusted input and will not open you to SQL injection issues. But you can't use quote_ident for values as you're trying to do in your example. The string you're passing to cursor.execute() will end up being (for name foobar) SELECT * FROM students WHERE name = "foobar";, which will try to find rows where the name column is equal to the foobar column, not where name is equal to the string 'foobar'.

Related

Difficult in converting to strings from a list

I have a list which is in below format
A = [ "machine's code" ,"max's code"]
I want to convert to that list to string and pass it to a query. I am using python for this.
I am trying with below query and not giving required results
for i in A:query=Select * from table where name='"+str(A)+"'"
Expected code should be :
Select * from table where name="machine's code"
list_of_queries = []
for element in A:
query = f'Select * from table where name="{el}"'
list_of_queries.append(query)
as pointed out by others here, this pattern should be only used internally, as it creates some sql injection security risks.

when I shoud use format() function and str() function. which one is better?

I am stuck to find out better one between str() and format() in python
"SELECT schools.deis_income , schools.school_name,SUM(money.coin_in_amount) AS coinamount, SUM(money.note_in_amount) AS noteamount , SUM(money.coffee_coin_in_amount) AS coffeeamount , SUM(money.coin_out_amount) AS coinoutamount, SUM(money.note_out_amount) AS noteoutamount FROM money_transactions AS money JOIN school_admin_details AS sa on sa.id = money.school_admin_id JOIN schools ON schools.id=sa.school_id WHERE sa.school_id ={school_id} AND money.transaction_time BETWEEN '{start_date}' AND '{end_date}' GROUP BY schools.id".format(school_id=school_id,start_date=start_date,end_date=end_date)
I use format function here. can I use str() ?
please tell me which one give me quick result, str() or format() ???
If your question is which of this:
foo = "some text " + str(some_var) + " and some other text"
or this:
foo = "some text {} and some other text".format(var)
is "better", the general consensus is very clear: string formatting is much easier to read and maintain and the one pythonic way to go.
Now for your particular example, the answer is that both are totally wrong - unless you're ok to give full access to your database to even the most inept script kiddie. For SQL queries, the proper solution is to use prepared statements, where your db connector will take care of proper formatting and sanitizing of the values:
# assumes MySQL - for other vendors check your own
# db-api connector's doc for the correct placeholder
query = "SELECT somefield FROM mytable where somedate > %(somedate)s and something_else = %(someval)s"
cursor.execute(query, {"somedate": some_date, "someval": 42})

Struct name from variable in Matlab

I have created a structure containing a few different fields. The fields contain data from a number of different subjects/participants.
At the beginning of the script I prompt the user to enter the "Subject number" like so:
prompt='Enter the subject number in the format SUB_n: ';
SUB=input(prompt,'s');
Example SUB_34 for the 34th subject.
I want to then name my structure such that it contains this string... i.e. I want the name of my structure to be SUB_34, e.g. SUB_34.field1. But I don't know how to do this.
I know that you can assign strings to a specific field name for example for structure S if I want field1 to be called z then
S=struct;
field1='z';
S.(field1);
works but it does not work for the structure name.
Can anyone help?
Thanks
Rather than creating structures named SUB_34 I would strongly recommend just using an array of structures instead and having the user simply input the subject number.
number = input('Subject Number')
S(number) = data_struct
Then you could simply find it again using:
subject = S(number);
If you really insist on it, you could use the method proposed in the comment by #Sembei using eval to get the struct. You really should not do this though
S = eval([SUB, ';']);
Or to set the structure
eval([SUB, ' = mydata;']);
One (of many) reasons not to do this is that I could enter the following at your prompt:
>> prompt = 'Enter the subject number in the format SUB_n: ';
>> SUB = input(prompt, 's');
>> eval([SUB, ' = mydata;']);
And I enter:
clear all; SUB_34
This would have the unforeseen consequence that it would remove all of your data since eval evaluates the input string as a command. Using eval on user input assumes that the user is never going to ever write something malformed or malicious, accidentally or otherwise.

Importing data from Excel into Access using DAO and WHERE clause

I need to import certain information from an Excel file into an Access DB and in order to do this, I am using DAO.
The user gets the excel source file from a system, he does not need to directly interact with it. This source file has 10 columns and I would need to retrieve only certain records from it.
I am using this to retrieve all the records:
Set destinationFile = CurrentDb
Set dbtmp = OpenDatabase(sourceFile, False, True, "Excel 8.0;")
DoEvents
Set rs = dbtmp.OpenRecordset("SELECT * FROM [EEX_Avail_Cap_ALL_DEU_D1_S_Y1$A1:J65536]")
My problem comes when I want to retrieve only certain records using a WHERE clause. The name of the field where I want to apply the clause is 'Date (UCT)' (remember that the user gets this source file from another system) and I can not get the WHERE clause to work on it. If I apply the WHERE clause on another field, whose name does not have ( ) or spaces, then it works. Example:
Set rs = dbtmp.OpenRecordset("SELECT * FROM [EEX_Avail_Cap_ALL_DEU_D1_S_Y1$A1:J65536] WHERE Other = 12925")
The previous instruction will retrieve only the number of records where the field Other has the value 12925.
Could anyone please tell me how can I achieve the same result but with a field name that has spaces and parenthesis i.e. 'Date (UCT)' ?
Thank you very much.
Octavio
Try enclosing the field name in square brackets:
SELECT * FROM [EEX_Avail_Cap_ALL_DEU_D1_S_Y1$A1:J65536] WHERE [Date (UCT)] = 12925
or if it's a date we are looking for:
SELECT * FROM [EEX_Avail_Cap_ALL_DEU_D1_S_Y1$A1:J65536] WHERE [Date (UCT)] = #02/14/13#;
To use date literal you must enclose it in # characters and write the date in MM/DD/YY format regardless of any regional settings on your machine

How to convert string into a table

For example I loaded a module, and there is a table in this module with name "Table1". In the main file I have a table which I want to be the exact same copy of "Table1".
So how can I do it, if I have only a name of that table.
When I am trying to do it like this
str = "Table1"
t = str
I obviously get a string instead of table, so how can I get a table content that table content? What I want is to able somehow make this line of code
t = 'Table1'
be equvalent to this one
t = Table1
If str is the name of a global variable, use _G[str] to get its value.
Tables in Lua are a very flexible and important datatype. So much, that even modules are tables. If you know, that there is a table by a given name in the module, and you have it's name in a variable, just use the [] operator to get the table:
tablename = 'Table1' -- you get this from somewhere, assuming it's not fixed
require 'mymodule'
t = mymodule[tablename]
However, this is not a very good approach, because it assumes that you "know" that the module contains a table by the given name. You can always design modules that will export the table by a given standard name (which does not change):
require 'mymodule'
t = mymodule.Table1 -- equivalent to mymodule['Table1']

Resources