Retrieve Value from SQLITE Table and use to query another table - python

I am retrieving a value from a SQLITE table and then using this value to retrieve data from another table using a SELECT FROM WHERE statement. I cannot use the retrieved value to query the other table even though the values appear to match when I retrieve this value independently from the table I am querying. I get Error binding parameter 0 - probably unsupported type. I am passing the value I believe correctly from what I've read in the docs, but there is obviously something wrong.
Edit: The ulitmate goal is to select the Name and EndTime then insert the EndTime value in another table in the same db if a column value = Name in that table. Added Update code below that gives an idea of what I'm attempting to accomplish.
When I print nameItem it appears this is a unicode string, (u'Something') is how it appears. I don't know if this is an encoding issue, but I have used similar queries before and not run into this issue.
I have tried to use the text I am searching for directly in the SELECT query and this works, but when passing it as a variable I still get unsupported type.
c.execute('SELECT Name FROM Expected WHERE Timing = 1')
timeList = c.fetchall()
for i in range(len(timeList)):
nameItem = timeList[i]
c.execute('SELECT "EndTime" FROM Expected WHERE "Name" = ?', (nameItem,))
end = c.fetchone()
conn = sqlite3.connect(otherDb)
c = conn.cursor()
c.execute('UPDATE Individuals SET Ending = end WHERE NAME = NameItem')
I expect this to retrieve a time associated with the current value of nameItem.

The first fix to try is to use string instead of tuple (note timeList is list of tuples):
nameItem = timeList[i][0]
But better is to not use len, something like:
c.execute('SELECT Name FROM Expected WHERE Timing = 1')
timeList = c.fetchall()
for elem in timeList:
nameItem = elem[0]
c.execute('SELECT "EndTime" FROM Expected WHERE "Name" = ?', (nameItem,))
end = c.fetchone()
And even better is to fetch EndTime in the first query (looks acceptable in given context):
c.execute('SELECT Name, EndTime FROM Expected WHERE Timing = 1')
timeList = c.fetchall()
for elem in timeList:
name = elem[0]
end_time = elem[1]

Related

Illegal Variable Name/Number when Passing in Python List

I'm trying to run SQL statements through Python on a list.
By passing in a list, in this case date. Since i want to run multiple SELECT SQL queries and return them.
I've tested this by passing in integers, however when trying to pass in a date I am getting ORA-01036 error. Illegal variable name/number. I'm using an Oracle DB.
cursor = connection.cursor()
date = ["'01-DEC-21'", "'02-DEC-21'"]
sql = "select * from table1 where datestamp = :date"
for item in date:
cursor.execute(sql,id=item)
res=cursor.fetchall()
print(res)
Any suggestions to make this run?
You can't name a bind variable date, it's an illegal name. Also your named variable in cursor.execute should match the bind variable name. Try something like:
sql = "select * from table1 where datestamp = :date_input"
for item in date:
cursor.execute(sql,date_input=item)
res=cursor.fetchall()
print(res)
Some recommendation and warnings to your approach:
you should not depend on your default NLS date setting, while binding a String (e.g. "'01-DEC-21'") to a DATE column. (You probably need also remone one of the quotes).
You should ommit to fetch data in a loop if you can fetch them in one query (using an IN list)
use prepared statement
Example
date = ['01-DEC-21', '02-DEC-21']
This generates the query that uses bind variables for your input list
in_list = ','.join([f" TO_DATE(:d{ind},'DD-MON-RR','NLS_DATE_LANGUAGE = American')" for ind, d in enumerate(date)])
sql_query = "select * from table1 where datestamp in ( " + in_list + " )"
The sql_query generate is
select * from table1 where datestamp in
( TO_DATE(:d0,'DD-MON-RR','NLS_DATE_LANGUAGE = American'), TO_DATE(:d1,'DD-MON-RR','NLS_DATE_LANGUAGE = American') )
Note that the INlist contains one bind variable for each member of your input list.
Note also the usage of to_date with explicite mask and fixing the language to avoid problems with interpretation of the month abbreviation. (e.g. ORA-01843: not a valid month)
Now you can use the query to fetch the data in one pass
cur.prepare(sql_query)
cur.execute(None, date)
res = cur.fetchall()

Error involving SQLite 3 prevents me from adding to database properly

I've been working most of today on a function that creates a record in an sqlite table. I believe I am finally making some progress and it currently looks like this:
shopping = True
while shopping:
itemToAdd = input("Please enter the ID of the item to add to the basket: ")
basket.append(itemToAdd)
print(basket)
continueShop = input("Continue shopping?(y/n): ")
if continueShop == "n":
conn.execute("INSERT INTO Orders (UserID) VALUES (?)", (results[0][0],))
lastID = conn.execute("SELECT last_insert_rowid()")
conn.commit()
counter = 0
for items in basket:
createOrderItems = "INSERT INTO OrderItems (OrderID, ProductID) VALUES (?,?)"
conn.execute(createOrderItems, (lastID, basket[counter]))
counter = +1
conn.commit()
However, I am now encountering this error to do with lastID if I am reading the error correctly.
line 107, in
conn.execute(createOrderItems, (lastID, basket[counter])) sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.
I have 2 tables that I am currently attempting to use:
Orders - contains only an orderID and userID
OrderItems- contains OrderItemsID, OrderID (which i need to be the same as the OrderID Just added) and ProductID(which needs to be taken from the list created and looped to make a record for each item in the "basket".
When you do
lastID = conn.execute("SELECT last_insert_rowid()")
lastID gets bound to an sqlite3.Cursor:
To retrieve data after executing a SELECT statement, you can either treat the cursor as an iterator, call the cursor’s fetchone() method to retrieve a single matching row, or call fetchall() to get a list of the matching rows.
The cursor cannot be converted automatically to the raw ID. You'll have to pull it out yourself, e.g. by doing something like
row = lastID.fetchone()
row_id = row[0]
Then use row_id in your query instead of lastID.

How to update an integer value in an SQL record?

I'm pretty new to SQL and the Sqlite3 module and I want to edit the timestamps of all the records in my DB randomly.
import sqlite3
from time import time
import random
conn = sqlite3.connect('database.db')
c = sqlite3.Cursor(conn)
ts_new = round(time())
ts_old = 1537828957
difference = ts_new - ts_old
for i in range(1,309):
#getting a new, random timestamp
new_ts = ts_old + random.randint(0, difference)
t = (new_ts, i)
c.executemany("UPDATE questions SET timestamp = (?) WHERE rowid = (?)", t)
#conn.commit()
When run, I get a ValueError: parameters are of unsupported type.
To add the timestamp value originally I set t to a tuple and the current UNIX timestamp as the first value of a it e.g (1537828957, ). Is this error displaying because I've used two (?) unlike the single one I used in the statement to add the timestamps to begin with?
You're using executemany instead of execute. executemany takes an iterator of tuples and executes the query for each tuple.
You want to use execute instead, it executes the query once using your tuple.
c.execute('UPDATE questions SET timestamp = (?) where rowid = (?)', t)

Select single item in MYSQLdb - Python

I've been learning Python recently and have learned how to connect to the database and retrieve data from a database using MYSQLdb. However, all the examples show how to get multiple rows of data. I want to know how to retrieve only one row of data.
This is my current method.
cur.execute("SELECT number, name FROM myTable WHERE id='" + id + "'")
results = cur.fetchall()
number = 0
name = ""
for result in results:
number = result['number']
name = result['name']
It seems redundant to do for result in results: since I know there is only going to be one result.
How can I just get one row of data without using the for loop?
.fetchone() to the rescue:
result = cur.fetchone()
use .pop()
if results:
result = results.pop()
number = result['number']
name = result['name']

Comparing tuple elements against integers with Python

I am having a hard time converting data. I select the data from my database, which is returned in tuple format. I try to convert them using list(), but all I get is a list of tuples. I am trying to compare them to integers which i receive from parsing my JSON. What would be the easiest way to convert and compare these two?
from DBConnection import db
import pymssql
from data import JsonParse
db.execute('select id from party where partyid = 1')
parse = JsonParse.Parse()
for row in cursor:
curList = list(cursor)
i = 0
for testData in parse:
print curList[i], testData['data']
i += 1
Output:
(6042,) 6042
(6043,) 6043
(6044,) 6044
(6045,) 6045
SQL results always come as rows, which are sequences of columns; this is true even if there is just one column in each row.
Next, you are executing the query on the db object (whatever that may be), but are iterating over the cursor; if this works at all is more down to luck. You'd normally execute a query on the cursor object.
If you expect just one row to be returned, you can use cursor.fetchone() to retrieve that one row. Your for row in cursor loop is actually skipping the first row.
You could use:
cursor = connection.cursor()
cursor.execute('select id from party where partyid = 1')
result = cursor.fetchone()[0]
to retrieve the first column of the first row, or you could use tuple assignment:
cursor = connection.cursor()
cursor.execute('select id from party where partyid = 1')
result, = cursor.fetchone()
If you do need to match against multiple rows, you could use a list comprehension to extract all those id columns:
cursor = connection.cursor()
cursor.execute('select id from party where partyid = 1')
result = [row[0] for row in cursor]
Now you have a list of id values.
Quick and dirty:
print curList[i][0], testData['data']
Or how about:
for db_tuple, json_int in zip(cursor, parse):
print db_tuple[0], json_int

Categories

Resources