How to pass a variable to MySQL's LIMIT clause? - python

I am trying to make a SELECT statement to Mysql datbase using pymysql.
This is the code. I am passing a variable to the select statement, and to my surprise this is a huge pain in the lemon. Any idea what am I missing here?
def getUrlFromDatabase(n):
stmt = "SELECT * FROM jsonTes ORDER BY website LIMIT %s-1,1"
cur.execute(stmt,str(n))
return cur.fetchone()
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='passwd', db='email_database', charset='utf8')
cur = conn.cursor()
cur.execute("USE database")
getUrlFromDatabase(0)
Error:
This is what I try to achieve: Return the nth record from MySQL query
pymysql.err.ProgrammingError: (1064, "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 ''0'-1,1' at line 1")

LIMIT in MySQL takes numeric arguments, which must both be nonnegative integer constants. You have to calculate the expression in Python and then pass the integer as a single parameter. Also, you need to put the parameter in a tuple:
def getUrlFromDatabase(n):
stmt = "SELECT * FROM jsonTes ORDER BY website LIMIT %s, 1"
cur.execute(stmt, (n-1 if n > 0 else 0,))
return cur.fetchone()

You are not passing the value 1 for %s in the string format.
stmt = "SELECT * FROM jsonTes ORDER BY website LIMIT %s" %n for limit n

you can use like that
def getUrlFromDatabase(n):
stmt = "SELECT * FROM jsonTes ORDER BY website LIMIT {}, 1"
cur.execute(stmt.format(n-1 if n > 0 else n))
return cur.fetchone()

Related

Python MySQL Parameter Query Programming Error: 1064 (42000)

I want to query MySQL tables using python program but I got this error:
ProgrammingError: 1064 (42000): 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 ''10' OFFSET '0'' at line 1
The confusing thing is that when I don't use variables, the query runs perfectly as it is shown below:
cur = connection.cursor()
query = "SELECT * FROM DB.Table LIMIT 10 OFFSET 0"
cur.execute(query)
records = cur.fetchall()
for record in records:
print(record)
But I need to select data batch by batch and I have to do the above command in a for loop. And I need to define variables. But I got error 1064. Here is the code with error:
i = 0
p = str(i)
j = 10
q = str(j)
cur = connection.cursor()
query = "SELECT * FROM DB.Table LIMIT %s OFFSET %s"
cur.execute(query,(q,p,))
records = cur.fetchall()
for record in records:
print(record)
I appreciate your help.
Simply, do not convert parameterized values to string as error shows single quotes:
i = 0
j = 10
cur = connection.cursor()
query = "SELECT * FROM DB.Table LIMIT %s OFFSET %s"
cur.execute(query, (j, i))
You can use cur.execute(query % (q,p)) or
query = "SELECT * FROM DB.Table LIMIT {} OFFSET {}"
cur.execute(query.format(q, p))

Psycopg2 query remove \n from args

Im using python3 and postgres 11.5.
This is the script :
a = cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
for table in a:
cursor.execute("SELECT * FROM pg_prewarm(public.%s)", [table[0]])
a query gets some table names , and the loop query should run table name as the %s.
but for some reason i get the arg table[0] with // /n in the query and its messing it up.
if i print a results i get table names as tuple:
[('sa1591354519',), ('sa1591397719',), ('sa1591397719',)]
so [table[0]] is a string.
the error i get:
1574683839 [16177], ERR, execute ({'Error while connecting to PostgreSQL': SyntaxError('syntax error at or near "\'sa1591440919\'"\nLINE 1: SELECT * FROM pg_prewarm(public.\'sa1591440919\')\n ^\n')},)
what can i do ?
The errors don't have anything to do with the newlines you see, which are just an artifact of the error message. If you were to print out the error, would see:
syntax error at or near "'sa1591440919'"
LINE 1: SELECT * FROM pg_prewarm(public.'sa1591440919')
^
In other words, Postgres doesn't like the table name you're passing because it contains quotes. This is happening because you're trying to treat the table names like a normal query parameter, which causes psycopg to quote them...but that's not what you want in this case.
Just replace your use of query templating with normal Python string substitution:
a = cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
for table in a:
cursor.execute("SELECT * FROM pg_prewarm(public.%s)" % (table[0]))
But this won't actually work, because cursor.execute doesn't return a value, so a will be None. You would need to do something like:
cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
a = cursor.fetchall()
for table in a:
...

How do you read individual values from the same row in a database with sqlite?

I am attempting to read 2 values from the same row in a database but I am only good enough to read the entire line at once. I have added all the code that I think will be relevant:
def find(search, term):
# Helper function for the find function.
with connect("GTINb.db") as db:
cursor = db.cursor()
sql = "select * from GTINb where {} = ?".format(search)
cursor.execute(sql,(term,))
db.commit()
results = cursor.fetchall()
new = str(term)
if results:
results = str(results)
temp = open('temp.txt', 'a')
temp.write(results)
temp.write('\n')
temp.close()
with connect("GTINb.db") as db:
cursor.execute("UPDATE GTINb SET stockcur=stockcur-1 WHERE GTIN8=(?)",(new,))
cur = cursor.execute("SELECT stockcur from GTINb by (?)",(new,))
re = cursor.execute("SELECT restock from GTINb by (?)",(new,))
if cur < re:
cursor.execute("UPDATE GTINb SET stockcur=stockcur+10 WHERE GTIN8=(?)",(new,))
return print('More stock has been ordered in as stocks were low')
else:
return
else:
temp = open('temp.txt', 'a')
temp.write('Product not found')
temp.write('\n')
temp.close()
return
I am currently getting the error sqlite3.OperationalError: near "(": syntax error, and have tried replacing the '(?)' with %s, (%s) and ? with no success, coming up with the following error messages:
sqlite3.OperationalError: near "12345670": syntax error // where 12345670 was the input represented by new
sqlite3.OperationalError: near "(": syntax error
sqlite3.OperationalError: near "?": syntax error
Is there another way of doing this or have I made a simple mistake?
None of the SQL statements you've written are valid SQL. Please consult the SQLite documentation for the valid syntax.
Briefly:
UPDATE GTINb SET stockcur=stockcur-1 WHERE GTIN8=(?)
SELECT stockcur from GTINb by (?)
SELECT restock from GTINb by (?)
should be
UPDATE GTINb SET stockcur=stockcur-1 WHERE GTIN8 = ?
SELECT stockcur FROM GTINb WHERE GTIN8 = ?
SELECT restock FROM GTINb WHERE GTIN8 = ?
although the first one will probably execute with the unneeded parentheses.
Once you have your SQL working you will find that the second two statements can be combined into
SELECT stockcur, restock FROM GTINb WHERE GTIN8 = ?
which I believe is what you were asking about.

mysql is showing error in the syntax

I am having trouble in executing this query in python. I have an IP database which has 3 column startip, endip and country. Now I want to the location of the ip. this is my code
def get_country(ip):
try:
conn = MySQLConnection(host='localhost', database='ipdb', user ='root', password='password')
cursor = conn.cursor()
query = 'SELECT * FROM db6 WHERE %s BETWEEN INET_ATON(startip) AND INET_ATON(endip)'
ip_inint= ip2int(ip)
cursor.execute(query,ip_inint)
row = cursor.fetchone()
while row is not None:
print " Start range %s end range %s country %s " %(row[0], row[1], row[2])
row = cursor.fetchone()
except Error as error:
print(error)
ip2int function is
def ip2int(addr):
return struct.unpack("!I", socket.inet_aton(addr))[0]
error i am receiving is
1064 (42000): 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 '%s BETWEEN INET_ATON(startip) AND INET_ATON(endip)' at line 1
what could be the issue?
You need to pass a tuple to execute():
cursor.execute(query, (ip_inint,))
A list will probably work too:
cursor.execute(query, [ip_inint])
An alternative is to use a dictionary with named variables in the query:
query = 'SELECT * FROM db6 WHERE %(ip_inint)s BETWEEN INET_ATON(startip) AND INET_ATON(endip)'
cursor.execute(query, {'ip_inint': ip_inint})
Reference: http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

Using placeholders in a database query doesn't work

I am querying a mysql database version 5.6.13 using python 2.7.
This works:
whichCustomer = str(1934)
qry = ("SELECT * FROM customers WHERE customerid = " + whichCustomer)
cursor.execute(qry)
The query also works:
qry = ("SELECT * FROM customers WHERE customerid = 1934")
cursor.execute(qry)
BUT, when I try to use string substitution the query fails:
whichCustomer = 1934
qry = ("SELECT * FROM customers WHERE customerid = %d")
cursor.execute(qry, (whichCustomer))
Is there something I am missing. The full try/execute code follows:
try:
import mysql.connector
print 'Module mysql initialized'
print 'Attempting connection to cheer database'
cnx = mysql.connector.connect(user='notsure',
password='notsure',
host='localhost',
database='notreal')
cursor = cnx.cursor()
whichCustomer = str(1934)
qry = ("SELECT * FROM customers WHERE customerid = " + whichCustomer)
cursor.execute(qry)
recx = cursor.fetchone()
print recx[1]
cnx.close()
print 'Successful connection to notreal database'
except:
print 'Error initialzing mysql databsasr'
You need to use %s for SQL parameters, and the second argument must be a sequence, like a tuple:
whichCustomer = 1934
qry = ("SELECT * FROM customers WHERE customerid = %s")
cursor.execute(qry, (whichCustomer,))
Note the comma in the second parameter; without a comma, that parameter is not a tuple and just the 1934 integer value is passed in instead.
Although both Python string interpolation placeholders and SQL parameters use closely related syntax, they are not the same thing. As such, SQL parameters for positional values are always expressed as %s regardless of the type.

Categories