Python pass arguments in to query error - python

I have the following code in python. I get this error ->tuple indices must be integers, not str
How can I pass these values into the query? I have other examples where this approach works perfectly, i don't understand why it's failling here.
def request_events_json(uei,interval,conn):
cur = conn.cursor()
events_query ="""select e.nodeid,n.nodelabel,e.ipaddr,count(*) as total,min(e.eventcreatetime),max(e.eventcreatetime),(regexp_matches (e.eventlogmsg,E': %(.*)'))[1] as msglog
from events e, node n where e.eventuei = (%s) and e.eventcreatetime > now() - interval (%s) and n.nodeid=e.nodeid
group by n.nodelabel,e.nodeid,e.ipaddr,msglog
order by e.nodeid, count(*) desc limit 10;"""
try:
print('## Requesting events ##')
cur.execute(events_query,('uei.opennms.org/syslogd/cisco/line','5 min'))
.......

With my version of PostgreSQL the round brackets after interval are forbidden.
Update:
It is the percent-sign in the regexp. Double it.

Related

How to print SQLAlchemy update query?

According to docs printing queries is as simple as print(query).
But according to update function description, it returns an integer
:return: the count of rows matched as returned by the database's
"row count" feature.
My code:
state = 'router_in_use'
q = self.db_session.query(Router).filter(
Router.id == self.router_id,
).update(
{Router.state: state}, synchronize_session=False
)
#print(q) outputs just 1
self.db_session.commit()
Is there a way to print q query in SQL language?
Query itself works fine.
python 3.8

Running a system Stored Procedure of SQL Server using python pyodbc

I am trying to run a system SP (which is a pre-built) using python pyodbc. In fact I am trying to see the dependencies on a table using sp_depends '<Object name>';
I am using the below code snippet.
df_f=[]
l_table = ['table_1','table_2','table_3']
try:
for l in l_table:
sql = """EXEC sp_depends '{0}';""".format(l)
while cur.nextset():
cur.execute(sql)
c = cur.fetchall()
df_l= pd.DataFrame.from_records(c, columns = [desc[0] for desc in cur.description])
df_l['Referenced_Object'] = l
df_f.append(df_l)
break
except pyodbc.Error as err:
s = str(err)
print(s)
finally:
cur.close()
cnxn.close()
The above code is not running. It is not throwing error but not appending anything in df_f.
If I run the above SP separately, I am getting the below error:
ProgrammingError: No results. Previous SQL was not a query.
I have taken help from this SO thread.
I am not able to SET NOCOUNT ON in this SP as this is a built-in and therefore I am not able to get the desired information in dataframe.
Any clue on this?
As I mentioned in the comments, sp_depends has been deprecated; it should not be used. As per the documentation you should be using sys.dm_sql_referencing_entities and sys.dm_sql_referenced_entities instead.
You can get similar results to the sp_depends with the following queries. You would need to replace the variables with parameters from your programming language (not inject them):
SELECT CONCAT(re.referenced_schema_name,'.', re.referenced_entity_name) AS [name],
o.type_desc AS [Type],
CASE re.is_updated WHEN 0 THEN 'no' WHEN 1 THEN 'yes' END AS updated,
CASE re.is_selected WHEN 0 THEN 'no' WHEN 1 THEN 'yes' END AS selected,
re.referenced_minor_name AS [column]
FROM sys.dm_sql_referenced_entities(QUOTENAME(#SchemaName) + N'.' + QUOTENAME(#ObjectName) ,'OBJECT') re
JOIN sys.objects o ON re.referenced_id = o.object_id;
SELECT DISTINCT
CONCAT(re.referencing_schema_name,'.', re.referencing_entity_name) AS [name],
o.type_desc AS [Type]
FROM sys.dm_sql_referencing_entities(QUOTENAME(#SchemaName) + N'.' + QUOTENAME(#ObjectName) ,'OBJECT') re
JOIN sys.objects o ON re.referencing_id = o.object_id;

Python SQL Select Syntax with variable in between

I have a SQL statement that works in mysql:
SELECT * FROM `ps_message` WHERE `id_order` = 111 ORDER BY id_message asc LIMIT 1
What is wrong with the following statement in Python:
cursor2.execute("SELECT * FROM ps_message WHERE id_order='%s'" % order["id_order"] " ORDER BY id_message asc LIMIT 1")
How should the syntax be in Python to work?
You have a syntax error in string formatting. Should be:
cursor2.execute("SELECT * FROM ps_message WHERE id_order='%s' ORDER BY id_message asc LIMIT 1" % order["id_order"])
Using format() is also preferable over old-style string formatting. Read more about it here.
Pass the order number as a query parameter.
e.g.
cursor2.execute("SELECT * FROM ps_message WHERE id_order=%s ORDER BY id_message asc LIMIT 1", [ order["id_order"] ])
Note that when using query parameters you don't put quotes around the %s.
This approach is recommended to avoid the risk of sql injection attacks.
It should also be more efficient if there are many queries.
https://docs.python.org/2/library/sqlite3.html
http://pymssql.org/en/stable/pymssql_examples.html

PyMySQL Join Query is empty

I have a query that works perfectly in plain MySQL:
SELECT * FROM `ls_matches` AS m
LEFT JOIN `ls_regions` AS r
ON r.id = m.region
WHERE
m.crawled = FALSE
I am using PyMySQL lib to make a query, but the "same" query is empty:
sql = "SELECT * FROM `ls_matches` AS m"\
"LEFT JOIN `ls_regions` AS r"\
"ON r.id = m.region"\
"WHERE"\
"m.crawled = %s"
cursor.execute(sql, (False,))
results = cursor.fetchall()
pprint(results)
Any ideas on why this is empty? W/out the JOIN it works perfectly, so the issue is somewhere with that I think!
Any hints highly appreciated!
You need to check errors.
How about this?
sql = """
SELECT *
FROM `ls_matches` m LEFT JOIN
`ls_regions` r
ON r.id = m.region
WHERE m.crawled = '%s'
"""
Python gives you the ability to have strings that span multiple lines. Use the capabilities of the language.
I would also encourage you to use parameters rather than stuffing values into the string, but that is a different issue.

Python and MySQLdb

I have the following query that I'm executing using a Python script (by using the MySQLdb module).
conn=MySQLdb.connect (host = "localhost", user = "root",passwd = "<password>",db = "test")
cursor = conn.cursor ()
preamble='set #radius=%s; set #o_lat=%s; set #o_lon=%s; '%(radius,latitude,longitude)
query='SELECT *, (6371*1000 * acos(cos(radians(#o_lat)) * cos(radians(lat)) * cos(radians(lon) - radians(#o_lon)) + sin(radians(#o_lat)) * sin(radians(lat))) as distance FROM poi_table HAVING distance < #radius ORDER BY distance ASC LIMIT 0, 50)'
complete_query=preamble+query
results=cursor.execute (complete_query)
print results
The values of radius, latitude, and longitude are not important, but they are being defined when the script executes. What bothers me is that the snippet of code above returns no results; essentially meaning that the way that the query is being executed is wonky. I executed the SQL query (including the set variables with actual values, and it returned the correct number of results).
If I modify the query to just be a simple SELECT FROM query (SELECT * FROM poi_table) it returns results. What is going on here?
EDIT: Encapsulated Haversine formula calculation within parenthesis
AFAIK you can't run multiple statements using execute().
You can, however, let MySQLdb handle the value substitutions.
Note that there are two arguments being passed to execute().
Also, just running execute() doesn't actually return any results.
You need to use fetchone() or fetchmany() or fetchall().
cursor.execute('''
SELECT *,
6371*1000 * acos(cos(radians(%s)) *
cos(radians(lat)) * cos(radians(lon) - radians(%s)) +
sin(radians(%s)) * sin(radians(lat))) as distance
FROM
poi_table
WHERE distance < %s
ORDER BY distance ASC
LIMIT 0, 50''', (latitude, longitude, latitude, radius,))
results = cursor.fetchall()
print results
Are you sure that the HAVING clause shouldn't be WHERE distance < #radius instead?

Categories