TypeError sqlite python - python

I am new to sqlite in python and I am trying to do the following:
Extract a certain value from a row in a table and compare it to 100 (it's an INT type normally).
school is a table where I have the following attributes: id, class, nbstudent, nbteachers, nbrepresentative
I use the following function:
def select_school_value(conn, class,m):
"""
Query school by class
"""
cur = conn.cursor()
cur.execute("SELECT * FROM school WHERE class=?", (class,))
record = cur.fetchone()
return record[m]
The function's parameter m is just a number that depends on which attribute I want to extract for the comparaison: nbstudent is m=2, nbteacher is m=3..
When I use my function select_school_value() and compare the returned value with 100, I have a TypeError, the return is a NoneType.
How can I have a integer type return (the type of the attribute I need)?
Thank you in advance.

I guess the issue is in class parameter that you pass to your function and query. Rename it somehow, because Python treats it like a pointer to some class within python code.
Also you have that class=? part which means actuallly "find a class which equals '?'". It should be rewritten too.
I suggest trying this:
def select_school_value(conn,cl,m):
"""
Query school by class
"""
cur = conn.cursor()
cur.execute("SELECT * FROM school WHERE class={}".format(cl))
record = cur.fetchone()
return record[m]

Related

How to make a query with whereIn with json values sqlalchemy

I want to make a query in sqlalchemy with a json, but this query should be of the type whereIn where the values ​​are in the values ​​I give them
For examples I give
class Product(Base):
def __init__(self):
super(Product, self).__init__()
self.product = self.Base.classes.products
self.session = Session(self.engine)
def get_products(self, data):
print(data)
query = self.session.query(self.product)
product = query.filter(self.product.attributes.like(data['attributes']))
print(product.get())
In my database these attributes are like this
"[{\"Brand\":\"Kanu\"},{\"Shade\":\"Red, Yellow\"},{\"Material\":\"Artificial Leather\"}]"
How could I proceed?
Can sql alchemy make this difference or should I do the query manually?
What error I got
LINE 3: WHERE products.attributes LIKE '["{''Ideal For'': ''Women''}...
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.

Cannot access my nested function which is inside the class

So Inside a class I have a function and inside that function I have a series of functions. But I cannot call the nested function when I create the object.user.searchBooks.AuthorBooks() (where user is an instance of the object) does not work. I don't know whether I am doing this wrong. Is there another way of accessing the function
class User():
def __init__(self):
self.ID = None
self.Firstname = None
self.Surname = None
self.username = None
self.email = None
def searchBook(self):
'''Searching Books with given query'''
def AuthorBooks(self, aFirstname, aLastname, Type):
"""Query based on Author Searches - returns books with particular author """
if Type == 'All':
query = ("""
SELECT * FROM tblBooks;
SELECT * FROM tblAuthor;
SELECT cb.Name, cb.Genre, cb.Year_Published, ca.Firstname, ca.Surname
FROM tblBooks as cb
INNER JOIN tblAuthor ca on cb.AuthorID = ca.AuthorID
WHERE (UPPER(ca.Firstname)) = (UPPER(?)) or (UPPER(ca.Surname) = UPPER(?));""")
elif Type == 'Loaned Books':
query = ("""
SELECT tblBooks.Name, tblAuthor.Firstname, tblAuthor.Surname, tblBooks.BookID, tblLoans.Expiry_Date
FROM tblLoans
INNER JOIN (tblBooks INNER JOIN tblAuthor ON tblBooks.AuthorID = tblAuthor.AuthorID) ON tblBooks.BookID = tblLoans.BookID
WHERE ((UPPER(tblAuthor.Firstname) = UPPER(?)) or(UPPER(tblAuthor.Surname) = UPPER(?)) AND tblLoans.Date_of_Return IS NULL;
""")
cursor.execute(query, [(aFirstname), (aLastname)])
return cursor.fetchall()
Since the function AuthorBooks() is defined inside of searchBook(), this makes it inaccessible from outside of the searchBook() function. (All variables and functions defined inside of a function are generally only accessible within that function in which they were defined)
To make your code work, you could define AuthorBooks() as a separate function and access it directly using user.AuthorBooks().

How do I select a row in sqlite with a name on the row instead of an id with python?

I'm programming a store management system in python using sqlite as database. I want to be able to see Item price when the name of the item is entered instead of the Item id...below is the code snippet
def ajax2(self, *args, **kwargs):
self.get_name = self.entername_e.get()
#get the products info with that name or id and fill labels above
query = "SELECT * FROM inventory WHERE name=?"
result = c.execute(query, (self.get_name, ))
for self.r in result:
self.get_name = self.r[1] #name
self.get_price = self.r[4] #sp
self.get_stock = self.r[2] #stock
self.productname.configure(text="Product's Name: "+ str(self.get_name))
self.pprice.configure(text="Price: Gh "+str(self.get_price))
Anytime I run the code after entering the name in the label Entry, the name appears even if it's not in the database and an error message follows in the command line like below:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\GH\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in
__call__
return self.func(*args)
File "main.py", line 96, in ajax2
self.pprice.configure(text="Price: Gh "+str(self.get_price))
AttributeError: 'Application' object has no attribute 'get_price'
PS C:\Users\GH\Desktop\Developments\Store Management Software>
If the name is not present in the database, the cursor returned by the query is empty and the loop is not entered. As a result, self.get_name is unchanged and keeps the entered value, and self.get_price is not set, hence the error.
You shoud explicitely test for that case:
...
result = c.execute(query, (self.get_name, ))
empty = True
for self.r in result:
empty = False
self.get_name = self.r[1] #name
self.get_price = self.r[4] #sp
self.get_stock = self.r[2] #stock
if empty: // name is not present in database
...
I don't think that you understand the object oriented approach in this python code. The self keyword is used to access the underlying object, of which all the attributes should be defined in the init function of the class. These attributes should only be there to represent the state of an instantation of the class. See this link : link
You should always be careful when altering objects by accessing the attributes directly. A common practice is to only access them by getters and setters, e.g.
def getAttribute_1(self):
return self.attribute_1
There are lots of good books and tutorials about object oriented programming available if you want to learn more about it, just google it.
In this case, for example, I don't see why you do:
for self.r in result: ...
when you should let go off the self keyword:
for r in result: ...
As this result variable is only relevant within the scope of your function.
Furthermore, if you want to set the price attribute of your current object, you should define that attribute in the init function:
def __init__(self, ...)
self.price = 0 """or whatever default value
you want to give it, or initiate it by giving the initial
value as an argument for the constructor"""
maybe define a getter and setter like this:
def get_price(self):
return self.price
def set_price(self, new_price):
self.price = new_price
Then use these methods in your ajax function. Just remember to make a distinction between local variables, e.g. price = result[4] which are only relevant in this function, and attributes of your object, like self.price! These are 2 very different concepts.
To respond to your error in this example: the get_price is not set if the results returned by the query are None, in which case the loop will not be entered. In this case, the self.get_price attribute of you object has never been created, hence the error.
Hope this helps

PyQT: Using attributes from SQLite query

I am confused as to how I can use certain attributes that are returned after a query to a local SQLite database. I can populate a qlistwidget with one of the attributes but I do not know how to get the other attributes when a user clicks on the listwidget item.
The following code was created using Eric which pre populates some of the signals and slots
#pyqtSignature("QString")
def on_searchText_textEdited(self, p0):
"""
Slot documentation goes here.
"""
# TODO: not implemented yet
self.resultsList.clear()
self.searchItem = self.searchText.text()
self.search()
#pyqtSignature("QListWidgetItem*")
def on_resultsList_itemClicked(self, item):
"""
Slot documentation goes here.
"""
# TODO: not implemented yet
result = str(item.text())
QMessageBox.about(self, "Clicked Item", "%s")%(result)
#pyqtSignature("")
def on_cancelButton_clicked(self):
"""
Slot documentation goes here.
"""
self.close()
def search(self):
conn = sqlite3.connect("C:\\file.sqlite")
cur = conn.cursor()
sqlqry = "SELECT name, number, size FROM lookup WHERE name LIKE '%s' LIMIT 100;"%("%"+self.searchItem+"%")
try:
c = cur.execute(sqlqry)
data = c.fetchall()
for i in data:
self.resultsList.addItem(i[0])
except sqlite3.Error, e:
QMessageBox.about(self, "Error message", "Error")
So my resultsList gets populated when the user enters text into the line edit but then when a user clicks on an item I get an error with the messagebox saying something about a NoneType and str.
However, what I really need to use are the second and third attributes for somewhere else in my code.
So how do I select that attributes through the itemClicked signal and create two new variables?
i hope that makes sense, it has been a long day going round in circles
You just need to query from the database again and work with the new row.
#pyqtSignature("QListWidgetItem*")
def on_resultsList_itemClicked(self, item):
"""
Slot documentation goes here.
"""
result = str(item.text())
QMessageBox.about(self, "Clicked Item", "%s")%(result)
conn = sqlite3.connect("C:\\file.sqlite")
cur = conn.cursor()
sqlqry = "SELECT name, number, size FROM lookup WHERE name = '%s' LIMIT 1;"%(result)
try:
c = cur.execute(sqlqry)
data = c.fetchone()
# Do something with data
except sqlite3.Error, e:
QMessageBox.about(self, "Error fetching %s"%name, "Error")
Obviously, this doesn't deal with the database santisation issues you might have, and assumes that name is unique in the database.

Can I assign values in RowProxy using the sqlalchemy?

When I want to display some data in the web, the data need makeup, and I don't know how to achieve, here is the code:
from sqlalchemy import create_engine
engine = create_engine('mysql://root:111#localhost/test?charset=utf8')
conn = engine.connect()
articles = conn.execute('SELECT * FROM article')
articles = articles.fetchall()
for r in articles:
r['Tags'] = r['Keywords']
It tips that: 'RowProxy' object does not support item assignment.
What should I do for that?
The table 'article' contains the column 'Keywords', and not contains the column 'Tags'.
You can make a dict out of your RowProxy, which would support item assignment.
For example:
result_proxy = query.fetchall()
for row in result_proxy:
d = dict(row.items())
d['Tags'] = d['Keywords']
One nice trick with this is to use a subclass of a dict:
class DBRow(dict):
def __getattr__(self, key):
"""make values available as attributes"""
try:
return self[key]
except KeyError as error:
raise AttributeError(str(error))
#property
def something_calculated(self):
return self.a + self.b
row = DBRow(result_proxy_row, additional_value=123)
row["b"] = 2 * row.b
print something_calculated
The benefit of this is, that you can access the values still as attributes, plus you can have properties, which is a nice way to cleanup and massage the data coming from the database.

Categories