ORA-00933: SQL command not properly ended with psycopg2 - python

So I've been trying to get this query to run from python with psycopg2 but it gives me the error
ORA-00933: SQL command not properly ended
While if I try to run the query in the oracle DB it goes through without a problem.
All it does is get the count from one table and compare it with the count of another and returns PASS or FAIL.
If anyone could help identify what could be the cause I would be very grateful.
Here's the query:
'WITH QA AS ( SELECT COUNT(*) C FROM QAAUTO.FactInternetSales)
,DEV AS (SELECT COUNT (*) C FROM qaauto.LoyaltyProgramA)
SELECT "Records count" AS TEST_NAME
,QA.C AS QA_RECORDS
,DEV.C AS DEV_RECORDS
,CASE WHEN DEV.C > 0 AND DEV.C = QA.C THEN "PASS" ELSE "FAIL" END AS RESULT
FROM QA,DEV ; '
python code that runs it:
def generate_results(self, driver):
for tce in self.testCaseExecutors:
testExecutorId = tce["testcaseexecutorid"]
script = tce["script"]
failOutputScript = tce["failoutputscript"]
result = run_Script(driver, script)
output = None
if result == 'PASS':
stateid = 'PASS'
elif result == 'FAIL':
stateid = 'FAIL'
tcResult = (testExecutorId, stateid, output)
self.testCaseResults.append(tcResult)
def run_Script(driver, script):
result = driver.fetchall(script, {})
return result[0]
in my case script contains the query posted above

Apparently the semi-colon at the end of the query was causing the error.

Related

Python PYODBC: Previous SQL was not a query

I have gone through:
Error "Previous SQL was not a query" in Python?
MSSQL2008 - Pyodbc - Previous SQL was not a query
How to check if a result set is empty?
However none of them have resolved the issue.
The snippet from my db.py file is as follows:
result = cursor.execute(self.sql,self.params)
if result is None:
self.data = []
else:
self.data = [dict(zip([key[0] for key in cursor.description], row)) for row in result.fetchall()]
cnxn.close()
return self.data
This works for every SQL and stored procedure I have thrown at it except for this one
seq = request.form['seq']
s = 'EXEC sp_add ?, ?'
p = (udf.get_username(), int(seq))
l = Conn.testing(db="testingDatabase",sql=s,params=p)
I get the error:
Previous SQL was not a query
The SQL:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE sp_add
#user nvarchar(50),
#seq int
AS
BEGIN
SET NOCOUNT ON;
insert into tblName (userCol,seqCol) VALUES (#user,#seq)
END
GO
The stored procedure runs and the row gets inserted but the error shows up.
What I did instead was:
result = cursor.execute(self.sql,self.params)
cnxn.close()
return str(result)
This returns:
EXEC sp_add ?, ?
Why does it return that? Why does it return the statement I just passed to it?
In my SP, if I tag on a SELECT statement then the issue goes away.
Any suggestions other than the hack just mentioned?
According to the Python Database API PEP 249 specification, the return value of cursor.execute is not defined. So DB-APIs like pyodbc do not need to define consistent return value.
However, specifically for pyodbc, cursor.execute() returns a <pyodbc.Cursor> object which maintains the description attribute if object contains a value but will be None if an action command:
result = cursor.execute(self.sql, self.params)
if result.descripton is None:
self.data = []
else:
self.data = [
dict(zip([key[0] for key in cursor.description], row))
for row in
result.fetchall()
]
cnxn.close()
return self.data # METHODS INSIDE CLASSES DO NOT REQUIRE RETURN
Consider even a ternary operator:
result = cursor.execute(self.sql, self.params)
self.data = (
[
dict(zip([key[0] for key in result.description], row))
for row in result.fetchall()
]
if result.descripton is not None
else []
)
cnxn.close()
return self.data

Query results using odbc in python

import pyodbc as odbc
Driver = 'SQL Server'
server_name = ''
database_name = ''
conn = odbc.connect(f"""
Driver={{{Driver}}};
Server={server_name};
Database={database_name};
UID=;
PWD=;
""")
def sku_search():
SKU_check = '''SELECT [ITEMSKU] FROM
[StilettoXT].[dbo].[PRODDETAIL] WHERE
ITEMSKU = (?)'''
SKU_code = input('Please enter the SKU code: ')
cursor = conn.cursor()
cursor.execute(SKU_check, SKU_code)
if cursor.fetchall() == []:
print('Not Found')
elif cursor.fetchall() != []:
print('Found')
sku_search()
conn.close()
I'm having real difficulty trying to get the following code to work, specially the 'elif' part of the my if statement. If you run the script with an invalid SKU code that doesn't exists in that database, you get the print statement. If you run with a valid SKU code, nothing gets returned even though the cursor.fetchall() is not an empty list. If you swap the if and elif arguments round, you will only get a result for the 'if' part of the function. I can't understand why the 'elif' part returns nothing. If you query an invalid sku code, SQL will return a blank value. I've tried to reference this as None as well but the same issue.
Any suggestions would be greatly appreciated!

Why is my Python script setting all rows of my Postgres table as the same value?

I have a Python3 script that checks the validity of URL's stored in a database and prints either 'TRUE' or 'FALSE' in the terminal window depending on the result.
I'm trying to change it to upload the results into the same table but so currently it's just setting all rows in the column (url_valid type BOOL) as 'TRUE', unlike the printed results in the terminal which are correct.
I think it's because I don't include a "where" clause in my SQL queries, but that's because I'm not sure how to call the Python script's output from the SQL.
Other possibilities include my "cursor.execute(" or commit statements but I'm not sure.
Here's my code snippet:
dbconn = create_engine('postgresql+psycopg2://' + user + ':' + password + '#' + host + ':' + str(port) + '/' + database , echo=False)
dbconnraw = dbconn.raw_connection()
cur = dbconnraw.cursor()
cur.execute('SELECT email_domain_url FROM contacts_unlisted_umatch')
rows = cur.fetchall()
for row in rows:
try:
response = requests.get(row[0])
urlstat = response.status_code
if urlstat<400:
print('TRUE')
cur.execute("UPDATE contacts_unlisted_umatch SET url_valid = 'TRUE'")
dbconnraw.commit()
else:
print('FALSE')
cur.execute("UPDATE contacts_unlisted_umatch SET url_valid = 'FALSE'")
dbconnraw.commit()
except Exception:
print('FALSE')
cur.execute("UPDATE contacts_unlisted_umatch SET url_valid = 'FALSE'")
dbconnraw.commit()
pass
What can I change to update the value of each individual row instead of setting them all as 'TRUE'?
Add a "WHERE" clause to your SQL statements. Without the "WHERE" clause, you are telling it to update every row inside of of the table.
For example, "UPDATE contacts_unlisted_umatch SET url_valid = 'TRUE' where email_domain_url = ..." and this will update only that "email_domain_url"'s url_valid value.

PyMySQL Only returns query correctly first time round

Please consider the following:
I have a Python script that constantly checks a Database for new content by running a query.
def getTasks(database):
print "Checking for new tasks"
query = 'SELECT * FROM fosbot_tasks WHERE asked = %s'
args = (0)
try:
with database.cursor() as cursor:
cursor.execute(query, args)
return cursor.fetchall()
except database.Error as e:
print e
When the script first starts it returns all the correct data, however several seconds later it will re-run this function, I still see the "Checking for new tasks" in the console, however nothing is returned, no matter what is in the database.
If new content is added to the database where 'asked' is '0' it will not be picked up, nor if I change another already processed row (where asked == 1) back to 0, it just stays at 0 and is never found by the query.
Is there some sort of query response caching I am not aware of?
Any assistance will be appreciated.
Edit
Using the following:
def getTasks(database):
query = 'SELECT * FROM fosbot_tasks WHERE asked = %s'
args = (0,)
try:
with database.cursor() as cursor:
print "Checking for new tasks"
number_of_rows=cursor.execute(query, args)
print number_of_rows
return cursor.fetchall()
except database.Error as e:
print e
Results in:
Checking for new tasks
0
Checking for new tasks
0
Checking for new tasks
0
etc etc

Executing stored procedures in sqlalchemy

I am using a raw_connection in sqlalchemy to execute some SQL that runs a stored procedure.
the stored proc selects a parameter ID at the end.
How can I catch this ID?
the python code is:
import sqlalchemy as sa
SQLCommand = """
DECLARE #Msg varbinary(max) = CAST(%s AS varbinary(max) )
EXECUTE dbo.usp_procedure #Type = 32, #header = %s, #store = #Msg
""" % (Datacontent, var)
Engine = sa.create_engine(connection_string)
Connection = Engine.raw_connection()
cursor = Connection.cursor()
cursor.execute(SQLCommand)
return_key = list(cursor.fetchall())
Connection.commit()
Connection.close()
I thought return_key would contain the return code from usp_procedure but it errors out and I get:
No results. Previous SQL was not a query.
The procedure has as a final step:
SELECT #ParamID
I want to be able to read this code back in my python code
I don't have sql-serverand tested this only for oracle, however this is too long for a comment.
Created this simple stored procedure,
CREATE OR REPLACE PROCEDURE PROCEDURE1(inp IN VARCHAR2, outp OUT VARCHAR2) AS
BEGIN
IF (inp = 'true') THEN
outp := '1';
RETURN;
END IF;
IF (inp = 'false') THEN
outp := '0';
RETURN;
END IF;
outp := NULL;
RETURN;
END PROCEDURE1;
and tested it with the following code:
Connection = c.manager.engine.raw_connection()
cursor = Connection.cursor()
result = cursor.callproc("PROCEDURE1", ['true', ''])
print(result[1])
result = cursor.callproc("PROCEDURE1", ['false', ''])
print(result[1])
The results are 1 and 0 as expected.
I've been browsing around and I'd expect that callproc is available for sql-server e.g. here but not honestly I'm not what sqlalchemy will be using. Give it a try, hope it helps.

Categories