fetchall() throws "Previous SQL was not a query." for DELETE query - python

I have a python script which connects to sql server instance. I running a cte query to remove duplicates. The query run sucessfully but when i used the fetchall() function it results in an Error: the previous query is not a sql query and after checking in the db table for the duplicates, it shows the duplicate still exists. This is the same case with both pyodbc and sqlalchemy.
Code pyodbc:
import pyodbc
conn = pyodbc.connect(connection_string)
cursor = conn.cursor()
query = ''';with cte as
(
SELECT [ID], [TIME], ROW_NUMBER() OVER
(PARTITION BY [ID] order by [TIME] desc) as rn
from table
)delete from cte WHERE rn > 1'''
cursor.execute(query)
cursor.close()
conn.close()
Code for sqlalchemy:
from sqlalchemy import create_engine
from sqlalchemy.sql import text
import urllib
conn = urllib.parse.quote_plus(connection_string)
engine = create_engine('mssql+pyodbc:///?odbc_connect={}'.format(conn))
query = '''with cte as
(
SELECT [ID], [TIME], ROW_NUMBER() OVER (PARTITION BY [ID] order by [TIME] desc) as rn
from table
)
delete from cte WHERE rn > 1'''
connect = engine.connect()
result = connect.execute(query)
if result.returns_rows:
print("Duplicates removed")
else:
print("No row is returned")

when i used the fetchall() function it results in an Error: the previous query is not a sql query
This is the expected behaviour. Although your query includes a SELECT as part of the CTE, the query itself is ultimately a DELETE query which does not return rows. It will return a row count that you can retrieve with Cursor#rowcount, but Cursor#fetchall() will throw an error because there are no rows to retrieve.

Related

SQL INSERT, SELECT, UPDATE Queries With PyODBC

import pyodbc
cnxn_str = ("Driver={ODBC Driver 17 for SQL Server};"
"Server=#.#.#.#;"
"Database=DataBase;"
"PORT=1433;"
"UID=xxx;"
"PWD=xxx;")
cnxn = pyodbc.connect(cnxn_str)
//connect to sql database using connection string
cursor = cnxn.cursor()
sn_query ="SELECT **"
cursor.execute(sn_query)
//execute the select query
for row in cursor:
num= row[0]
print(num)
cursor = cnxn.cursor()
//execute the insert query
insert_bool_query ="INSERT into Table(name) values("The name you wan to insert");
cursor.execute(insert_bool_query)
for row in cursor:
print(row)
So I want to know whether if I can execute Select query, insert query and update query using only cursor.execute. In addition, if yes, then how to extract the rows for each query?

cx_Oracle: select query following an insert produces no result

in my python code I insert a value into a table.
In the table, there is a sequence which automatically assigns an ID.
After the insert, I want to get this it back in to my python application:
import cx_Oracle, sys
with cx_Oracle.connect(user=ORA_USER,password=ORA_PWD,dsn=ORA_DSN) as conn:
with conn.cursor() as cur:
cur.execute("Insert into my_table columns(data) values ('Hello')")
conn.commit()
with cx_Oracle.connect(user=ORA_USER,password=ORA_PWD,dsn=ORA_DSN) as conn:
with conn.cursor() as cur:
r = cur.execute("select id from my_table where data = 'Hello'")
print(r)
if r is None:
print("Cannot retrieve ID")
sys.exit()
Unfortunately, the result set r is always "None" even though the value has been inserted properly (checked via sqldeveloper).
What am I doing wrong?
I even open a new connection to be sure to grab the value...
After calling execute() for a SELECT statement you need to call fetchone(), fetchmany() or fetchall() as shown in the cx_Oracle documentation SQL Queries.
Or you can use an iterator:
with connection.cursor() as cursor:
try:
sql = """select systimestamp from dual"""
for r in cursor.execute(sql):
print(r)
sql = """select 123 from dual"""
(c_id,) = cursor.execute(sql).fetchone()
print(c_id)
except oracledb.Error as e:
error, = e.args
print(sql)
print('*'.rjust(error.offset+1, ' '))
print(error.message)
However to get an automatically generated ID returned without the overhead of an additional SELECT, you can change the INSERT statement to use a RETURNING INTO clause. There is an example in the cx_Oracle documentation DML RETURNING Bind Variables that shows an UPDATE. You can use similar syntax with INSERT.
With the table:
CREATE TABLE mytable
(myid NUMBER(11) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1),
mydata VARCHAR2(20));
You can insert and get the generated key like:
myidvar = cursor.var(int)
sql = "INSERT INTO mytable (mydata) VALUES ('abc') RETURNING myid INTO :bv"
cursor.execute(sql, bv=myidvar)
i, = myidvar.getvalue()
print(i)
If you just want a unique identifier you get the ROWID of an inserted row without needing a bind variable. Simple access cursor.lastrowid after executing an INSERT.

Why I got an error when I want to count the frequency of data for multiple table in mysql? Flask is used to create web app

I want to create a dashboard widget in my web app. The first step is to count the frequency of pos, neg and neu in mysql from two table. I tried to find the solution in Flask, but not many. Hope u can help me.
The error that I got is:
MySQLdb._exceptions.OperationalError: (1241, 'Operand should contain 1 column(s)')
Table in mysql:
ques9
ques10
My code:
#app.route('/we/<string:programid>')
def we(programid):
# Create cursor
cur = mysql.connection.cursor()
result = """SELECT(
(SELECT programid,sentiment, COUNT(*)
FROM ques9 AS question9
WHERE programid= %s
GROUP BY sentiment),
(SELECT programid,q10_sentiment, COUNT(*)
FROM ques10 AS question10
WHERE programid=%s
GROUP BY q10_sentiment ))"""
data_tuple = (programid, programid)
cur.execute(result, data_tuple)
program = cur.fetchall()
mysql.connection.commit()
if result > 0:
return render_template('we.html',program=program)
else:
msg = 'No Results Found'
return render_template('we.html', msg=msg)
# Close connection
cur.close()
The group by has to be after the where clause
So i posted all the python code, i thought about adding a try, but that you can look up
Your sql has some problems like the group an his own,l but your python code has also flaws, as you can see below. The variables for sql query and the data to send, i out there so that it looks somewhat cleanber
connection = mysql.connector.connect(host='localhost',
database='test_db',
user='user',
password='password')
cur = connection.cursor(prepared=True)
sql_update_query = """SELECT(
(SELECT programid,sentiment, COUNT(*)
FROM ques9 AS question9
WHERE programid= %s
GROUP BY sentiment),
(SELECT programid,q10_sentiment, COUNT(*)
FROM ques10 AS question10
WHERE programid=%s
GROUP BY q10_sentiment ))"""
data_tuple = (programid, programid)
cur .execute(sql_update_query, data_tuple)
connection.commit()
if (connection.is_connected()):
cur.close()
connection.close()

'Having' Clause in SQLite3 Python

I am trying to execute a SQL query in python. The query works well in SQL, throws error in python. The query is used to find all the duplicates in 'Excel_Values' table
Query:
WITH duplicates AS (
select CaseID, ColumnName, TabType, ColumnValue, count(*) from [Excel_Values]
where Validation_Key= 52
group by CaseID, ColumnName, TabType
having count(distinct ColumnValue) > 1
)
SELECT a.*
FROM [Excel_Values] a
JOIN duplicates b ON (a.CaseID = b.CaseID and a.ColumnName = b.ColumnName and a.TabType = b.TabType and a.Validation_Key = 52);

deleting data from multiple mysql tables using python

I want to delete some rows from almost 500 tables in mysql database using python.
I know that the query should be something like this:
DELETE FROM (table name)
[WHERE conditions] [ORDER BY ...] [LIMIT rows]
but I am not sure what should I use for the table name when I looping over the tables!
here is my loop
from mysql.connector import (connection)
# call databasecnx = connection.MySQLConnection(user='user', password='PW',host='127.0.0.1', database= 'database')
cursor = cnx.cursor()
cursor.execute("SHOW TABLES LIKE 'options_20%'")
table_names = [tables for (tables, ) in cursor]
for t in table_names:
cursor.execute("Delete table-refs WHERE Expiration = Datadate AND UnderlyingSymbol = 'SPY'")
cnx.commit()
I got an error:
You have an error in your SQL syntax; check the manual that...etc
Test with this.... You did'nt put from on your query statement.
for table in table_names:
cursor.execute("DELETE FROM"+ table +"WHERE Expiration = Datadate AND UnderlyingSymbol = 'SPY'")

Categories