Query results using odbc in python - 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!

Related

ORA-00933: SQL command not properly ended with psycopg2

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.

Python Pyodbc Binary Column is returning \xda\x08\xcd\x08\xba\x08 instead of numbers

I have a SQL database that displays a varbinary (max) like this 0x9406920691068F... I want to import it to python pycharm to get the same exact type of data.
However, it shows something like this instead
[b'\x94\x06\x92\x06\x91\x06\x8f\x06\x8d..
how do I copy the same numbers to python? I am a beginner in python, please help.
I copied the code from previous post and it didn't work
import pyodbc
def hexToString(binaryString):
try:
hashString = ["{0:0>2}".format(hex(b)[2:].upper()) for b in binaryString]
return '0x' + "".join(hashString)
except:
return binaryString
query = """ select P from Access.table """
conn_str = (
**** private database details # I don't copy on the page
)
cnxn = pyodbc.connect(conn_str)
cnxn.add_output_converter(pyodbc.SQL_BINARY, hexToString)
cursor = cnxn.cursor()
try:
cursor.execute(query)
row = cursor.fetchone()
except MySQLdb.error as err:
print(err)
else:
while row is not None:
print(row)
row = cursor.fetchone()
If the column return type is varbinary(max) then you need to add the output converter function to handle SQL_VARBINARY, not SQL_BINARY
cnxn.add_output_converter(pyodbc.SQL_VARBINARY, converter_function_name)

Pandas read_sql - ignoring error if table does not exist

I have a list of SQL scripts I have narrowed down and want to execute. The data in the list follows this pattern more or less:
[DROP TABLE ABC ....;, CREATE TABLE ABC ....;, INSERT INTO TABLE ABC .....;,UPDATE TABLE ABC .....;]
Then it repeats itself for the next table. All of this is confined to a single list below:
dfToList_P
The problem I am having is when a table doesn't exist, I want to ignore the error and execute the CREATE TABLE statement that follows it. Here is my code:
def load_test_table(self):
s = self.connection()
df = self.retrieve_sql()
df_P = df.loc[df['STEP_TYPE'] == 'P']
dfToList_P = df_P['SQL_SCRIPT'].tolist()
try:
for sql_script in dfToList_P:
#print(sql_script)
pd.read_sql(sql_script, s)
except teradata.DatabaseError as ex:
sql_state = ex.args[0]
if sql_state == 3807:
print('Tried to DROP table that did not exist:' + sql_script)
else:
print('DatabaseError in SQL Script: ' + sql_script)
I google'd around and added the try/except condition but I don't think that is actually doing anything in this instance.
Running the script errors out with:
pandas.io.sql.DatabaseError: Execution failed on sql 'DROP TABLE ABC;': (3807, "[42S02] [Teradata][ODBC Teradata Driver][Teradata Database](-3807)Object 'ABC' does not exist.")
Any ideas?
I figured it out, thanks to a combo of comments above. First, my Try/Except was in the incorrect location and also I switched from using pandas read_sql to just using regular session execute and it worked as expected. If table exists, drop it first, if not then create it.
Revised code below:
def load_test_table(self):
s = self.connection()
df = self.retrieve_sql()
df_P = df.loc[df['STEP_TYPE'] == 'P']
dfToList_P = df_P['SQL_SCRIPT'].tolist()
for sql_script in dfToList_P:
try:
s.execute(sql_script)
except teradata.DatabaseError as ex:
sql_state = ex.args[0]
if sql_state == 3807:
print('Tried to DROP table that did not exist:' + sql_script)
else:
print('DatabaseError in SQL Script: ' + sql_script)
continue

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.

MySQLdb - Check if row exists Python

I am trying to check if a row exist with the same Name my database with python and can't quite get it here is what I am trying: (I know the connection is wokring)
try:
cursor.execute("SELECT Name, COUNT(*) FROM Item_Info WHERE Name = %s GROUP BY Name"), (item_name)
catch:
print "it does not exist"
Can someone help me out here
Thanks
First of all you have a wrong syntax in your code. Python doesn't have a try...catch block. It has try...except block which is used like this:
try:
# something here
except:
# something here
MySQL does not return an error when you use SELECT command. However there are two different ways you can find out if it returned something or not.
PYTHON 2.7
cursor.execute(
"SELECT Name, COUNT(*) FROM Item_Info WHERE Name = %s GROUP BY Name",
(item_name,)
)
# gets the number of rows affected by the command executed
row_count = cursor.rowcount
print "number of affected rows: {}".format(row_count)
if row_count == 0:
print "It Does Not Exist"
PYTHON 3+
cursor.execute(
"SELECT Name, COUNT(*) FROM Item_Info WHERE Name = %s GROUP BY Name",
(item_name,)
)
# gets the number of rows affected by the command executed
row_count = cursor.rowcount
print ("number of affected rows: {}".format(row_count))
if row_count == 0:
print ("It Does Not Exist")
Another way to do this would be to fetch the statement and check if it is empty:
# execute statement same as above
msg = cursor.fetchone()
# check if it is empty and print error
if not msg:
print 'It does not exist'
This is my first answer, so I don't know how to style the code in the answer properly, it also seems messy because of that. Sorry for that.
Also i use Python 3 and pymysql, so there may be some syntax error but I have tried to write the code according to python 2.7 from what I could remember about it.
EDIT (5/1/2020)
Thanks to #Arishta for pointing out that the first method will require you to fetch all rows before using row_count. i.e adding cursor.fetchall() before the row_count = cursor.rowcount
cursor.execute(
"SELECT Name, COUNT(*) FROM Item_Info WHERE Name = %s GROUP BY Name",
(item_name,)
)
# Add THIS LINE
results = cursor.fetchall()
# gets the number of rows affected by the command executed
row_count = cursor.rowcount
print("number of affected rows: {}".format(row_count))
if row_count == 0:
print("It Does Not Exist")
Use the cursor.fetchone() if you only care if the record exists or not.
If you want to check for empty results, try if cur.description is None:
if cursor.description is None:
# No recordset for INSERT, UPDATE, CREATE, etc
pass
else:
# Recordset for SELECT
As well as:
exist = cursor.fetchone()
if exist is None:
... # does not exist
else:
... # exists
If you are running a statement that would never return a result set
(such as INSERT without RETURNING, or SELECT ... INTO), then you
do not need to call .fetchall(); there won't be a result set for
such statements. Calling .execute() is enough to run the statement.
cursor.execute("SELECT * FROM userinfo WHERE User_Name=%s",(userid,))
data="error" #initially just assign the value
for i in cursor:
data=i #if cursor has no data then loop will not run and value of data will be 'error'
if data=="error":
print("User Does not exist")
else:
print("User exist")

Categories