Python-MySQL : removing single quotes around variable values in query while running db.execute(str, vars) - python-3.x

I am running this code
def details(self, dbsettings, payload):
res = None
with UseDatabase(dbsettings) as db:
sql = "select * from %(tablename)s where userid = %(userid)s"
result = db.run_query_vals(sql, payload)
res = result.fetchall()
return res
but get an error
SQLError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''statuser' where userid = '14'' at line 1
The arguments being passed are :
sql = "select * from %(tablename)s where userid = %(userid)s"
payload = {'tablename' : 'statuser', 'userid' : 14}
As far as I understand, the query being passed to MySQL is along the lines of
select * from 'statuser' where userid = '14'
which is where I get the error; the tablename isnt supposed to be enclosed in quotes. How do I have the name included without the quotes/make them backquotes?
(I don't want to hard-code the table name - this is a variable and is initialised according to different parameters during class creation). Any help here?

You can use the .format() from string in python:
def details(self, dbsettings, payload):
res = None
with UseDatabase(dbsettings) as db:
sql = "select * from {tablename} where userid = {userid}"
sql = sql.format(**payload)
# result = db.run_query_vals(sql, payload) # Method to run query
res = result.fetchall()
return res

I encountered the same problem in pymysql and have figured out a solution:
rewrite the escape method in class 'pymysql.connections.Connection', which obviously adds "'" arround your string.
don't know whether it will help in your case, just sharing a possible way
similiar question: How to remove extra quotes in pymysql
Here's my code:
from pymysql.connections import Connection, converters
class MyConnect(Connection):
def escape(self, obj, mapping=None):
"""Escape whatever value you pass to it.
Non-standard, for internal use; do not use this in your applications.
"""
if isinstance(obj, str):
return self.escape_string(obj) # by default, it is :return "'" + self.escape_string(obj) + "'"
if isinstance(obj, (bytes, bytearray)):
ret = self._quote_bytes(obj)
if self._binary_prefix:
ret = "_binary" + ret
return ret
return converters.escape_item(obj, self.charset, mapping=mapping)
config = {'host':'', 'user':'', ...}
conn = MyConnect(**config)
cur = conn.cursor()

Related

Choose encoding when converting to Sqlite database

I am converting Mbox files to Sqlite db. I do not arrive to encode the db file into utf-8.
The Python console displays the following message when converting to db:
Error binding parameter 1 - probably unsupported type.
When I visualize my data on DB Browser for SQlite, special characters don't appear and the � symbol shows up instead.
I first convert .text files to Mbox files with the following function:
def makeMBox(fIn,fOut):
if not os.path.exists(fIn):
return False
if os.path.exists(fOut):
return False
out = open(fOut,"w")
lineNum = 0
# detect encoding
readsource = open(fIn,'rt').__next__
#fInCodec = tokenize.detect_encoding(readsource)[0]
fInCodec = 'UTF-8'
for line in open(fIn,'rt', encoding=fInCodec, errors="replace"):
if line.find("From ") == 0:
if lineNum != 0:
out.write("\n")
lineNum +=1
line = line.replace(" at ", "#")
out.write(line)
out.close()
return True
Then, I convert to sqlite db:
for k in dates:
db = sqlite_utils.Database("Courriels_Sqlite/Echanges_Discussion.db")
mbox = mailbox.mbox("Courriels_MBox/"+k+".mbox")
def to_insert():
for message in mbox.values():
Dionyversite = dict(message.items())
Dionyversite["payload"] = message.get_payload()
yield Dionyversite
try:
db["Dionyversite"].upsert_all(to_insert(), alter = True, pk = "Message-ID")
except sql.InterfaceError as e:
print(e)
Thank you for your help.
I found how to fix it:
def to_insert():
for message in mbox.values():
Dionyversite = dict(message.items())
Dionyversite["payload"] = message.get_payload(decode = True)
yield Dionyversite
``
As you can see, I add `decode = True` inside `get_payload`of the `to_insert`function.

Update Query with a variable instance

First and foremost, I must admit I am new to Python and SQL. Now, I will get the problem. I am trying to update a table where column_ID is equivalent to a variable. In the Python class I have a function with the following statement:
stName = self.txtName.text()
stUsername = self.txtUsername.text()
stPassword = self.txtPassword.text()
stMobile = self.txtMobile.text()
myID = self.txtID.text()
sql_update_query = """UPDATE signup SET name = %s, username = %s, password = %s, mobile = %s WHERE id = myID"""
input = (stName, stUsername, stPassword, stMobile)
curs.execute(sql_update_query, input)
conn.commit()
When I click the Update button to run this function, the system prompts 'Python has stopped working'.
Can someone assist me to fix the SQL statement?
myID needs to be passed as an argument to the sql statement.
sql_update_query = """UPDATE signup SET name = %s, username = %s, password = %s, mobile = %s WHERE id = %s"""
And
input = (stName, stUsername, stPassword, stMobile, myID)

Passing input into Curl command inside python3

I'm currently working with errbot, but i'm having trouble with allowing users to enter a message to be passed along with the curl command. my plugin looks as follows:
#arg_botcmd('team_key', type=str)
#arg_botcmd('--message' , dest='message', type=str)
def oncall_page(self, msg, team_key=None, message=None):
if team_key in page_list.keys():
team_id = page_list[team_key]
data = {"message_type":"CRITICAL","state_message":"{0}".format(message)}
response = requests.post('https://www.apiurl.com/{0}'.format( team_id), data)
yield "Paging {0} ".format( team_id )
My issue is with this line:
data = {"message_type":"CRITICAL","state_message":"{0}".format(message)}
This seems to be crashing the command completely, I'm hoping users can execute one command such as "!oncall page team_name --message "
Any help would be appreciated:)
#arg_botcmd('team_key', type=str)
#arg_botcmd('--message' , dest='message', type=str)
def oncall_page(self, msg, team_key=None, message=None):
if team_key in page_list.keys():
team_id = page_list[team_key]
text = str(message)
msg_type = "critical"
data = '{"message_type":"%s", "state_message":"%s"}' % (msg_type, text)
# data = '{"message_type":"critical", "state_message":"%s"}'(text)
URL = 'https://www.apiurl.com/{0}'.format( team_id)
response = requests.post(URL , data)
This is the fix for this!

How to use Groovy script in soapUi to loop multiple time

I am new to SoapUi. I am exploring on how multiple request in soapUi is done using groovy script.
below is the example that im trying to do, based on example that i found through "googling"
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.model.testsuite.*;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
import java.util.Random
import com.eviware.soapui.model.testsuite.TestRunner.Status
// Define your testCase pointer
//def testcase = testRunner.testCase.testSuite.project.testSuites["TestSuite - User Management REST API"].getTestCaseByName ("Authenticate User")
def counterUser = testRunner.testCase.testSuite.getPropertyValue( "counter" )
int value = counterUser.toInteger()
String tester = ""
30.times {
value = value + 1
tester = "tester " + value.toString()
testRunner.testCase.testSuite.setPropertyValue( "userName", tester )
testRunner.runTestStepByName("POST - createUser - Create a User")
}
testRunner.testCase.testSuite.setPropertyValue( "counter", value.toString() )
I want to create a 30 users which start from Tester1...tester2.....tester30.
Is it possible to do this way? I keep getting an error such as NullPointerException at this line
int value = counterUser.toInteger()
I got what you say.
That is because, initially there is no value for counter which results to null and you are applying toInteger() over it.
Just change:
From:
int value = counterUser.toInteger()
To:
int value = counterUser?.toInteger() ?: 0

Detect SQL injection in Groovy dynamic SQL

How can you detect SQL injection vulnerability in a Grails app with dynamic native SQL?
What I'm looking for is something that can tell the difference between this
def sql = new Sql(dataSource)
def dynamicWhereClause = ""
if (params.col) {
dynamicWhereClause = " and col = :col"
}
// OK because dynamic SQL does not concatenate user input
def sqlString = "select * from tab where ... ${dynamicWhereClause}"
sql.rows(sqlString, params)
and this
def sql = new Sql(dataSource)
def dynamicWhereClause = ""
if (params.col) {
// NOT OK - directly concatenating user input
dynamicWhereClause = " and col = '" + params.col + "'"
}
def sqlString = "select * from tab where ... ${dynamicWhereClause}"
sql.rows(sqlString)
Sonarqube/Findbugs has a rule like "prepared statement is generated from a nonconstant String" but that would not distinguish between the safe one and the dangerous one. What other options are out there?
How about using a Static Analysis tool such as "Find Security Bugs".
See here for others that are compatible with Groovy.

Resources