Im trying to get the data of a word through database with sqlite3 and python but when i try to call the read_from_db function, i have this error _init__() missing 1 required positional argument: 'receiver'. I cant seem to find what happened
heres the code
conn = sqlite3.connect('yeet1.db')
cursor = conn.cursor()
class Ui_WordWindow(object):
def __init__(self, receiver): #Inherit user-input word from another window
self.receiver = receiver
print(self.receiver) #Checking if it worked correctly
def read_From_db(self): #Read and print out data of user-input word
cursor.execute(('SELECT * FROM mytable WHERE Meaning = ?', self.receiver))
data = cursor.fetchall()
print(data)
window2 = Ui_WordWindow()
window2.read_From_db()
cursor.close()
conn.close
You declare the __init__ method of the class Ui_WordWindow like so:
def __init__(self, receiver): #Inherit user-input word from another window
And it does have a parameter receiver. The error you get indicates that when constructing a Ui_WordWindow you should provide exactly one parameter and that should be the value for receiver.
I.e. this line:
window2 = Ui_WordWindow()
Should in fact be:
window2 = Ui_WordWindow(receiver)
where receiver is a valid value for receiver.
The receiver object = "some value"
conn = sqlite3.connect('yeet1.db')
cursor = conn.cursor()
class Ui_WordWindow(object):
def __init__(self, receiver): #Inherit user-input word from another window
self.receiver = receiver
print(self.receiver) #Checking if it worked correctly
#when you print self.receiver it means the value which you are passing say for example "test"
def read_From_db(self): #Read and print out data of user-input word
cursor.execute(('SELECT * FROM mytable WHERE Meaning = ?', "test"))
# now the query becomes select * from mytable where meaning = 'test'
# the value 'test' is being passed by the receiver object and you need to provide that value
data = cursor.fetchall()
print(data)
window2 = Ui_WordWindow(receiver) # which has some value ex 'test'
window2.read_From_db()
cursor.close()
conn.close
you need to brush up on object oriented approach.
try reading from this: python object oriented
Related
I want to pass some values to a def but am having issues with properly adding this.
In
class MyAddin():
def __init__(self, imapinfopro, thisApplication): #also tried including _self.Table_Path in this.
try:
self._pro = imapinfopro
self._thisApplication = thisApplication
self._tab = None
#self._table_path =(r'D:\junk\28355.tab')
# Some standard variables to allow functions to be created for each action for easier use. r_ is for Ribbon actions
r_item_name="Infrastructure_Data" #Name of button on main ribbon (no spaces allowed)
r_button_name="Water" #same as operations in the ribbon_customization.py
r_subroup_name="Not Abandoned" #same as "Table" and "CallBack" in the ribbon_customization.py
r_subgroup_action="Open\nClose" #same as 'MB Handler\nNo Parameter'in the ribbon_customization.py
tab = self._pro.Ribbon.Tabs.Add(r_item_name)
self._tab = tab
if tab:
group = tab.Groups.Add(r_button_name, r_button_name)
if group:
button = group.Controls.Add("ButtonOpenTable", r_subroup_name, ControlType.Button)
button.IsLarge = True
button.LargeIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_32x32.png")
button.SmallIcon = CommonUtil.path_to_uri("pack://application:,,,/MapInfo.StyleResources;component/Images/Mapping/infoTool_16x16.png")
button.Command = AddinUtil.create_command(self.open_table_click)
except Exception as e:
print("Failed to load: {}".format(e))
def open_table_click(self, sender):
#table_path=(r'D:\junk\28355.tab') #if left in this is used to open the table but I want to get this value from button.Command above.
table = self._pro.Catalog.OpenTable(table_path)
CommonUtil.do("map from {}".format(table.Alias))
CommonUtil.do("browse * from {}".format(table.Alias))
pass
I want to send the value for table_path in to def open_table_click from button.Command = AddinUtil.create_command(self.open_table_click). If it wasn't a self call it would be ..._command(self.open_table_click, tablepath) and def open_table_click(self, sender, table_path):
I want to create a class with methods, so that I do not have to create multiple functions.
Below is my code, I want to get a class with two methods. Method 1: SQL Query, method 2: sql insert.
Any tipp is greatly appreciated.
Stefan
def dbconnect():
dbconn = pymysql.connect(host='192.168.1.2', port=3307, user='username', passwd='password', db='dbname')
try:
cur = dbconn.cursor()
sqlQuery = "select * from data"
sqlQuerygetlast = "SELECT * FROM data ORDER BY id DESC LIMIT 1"
sqlQuerygetlast10 = "SELECT * FROM data ORDER BY id DESC LIMIT 10"
cur.execute(sqlQuerygetlast10)
rows = cur.fetchall()
for row in rows:
print(row)
except Exception as e:
print("Exeception occured:{}".format(e))
finally:
#dbconn.commit()
dbconn.close()
My objective is to call the methods from my code, i.e. query a select statement.
Thanks a lot
Stefan
I guess you mean that you don't want to create multiple connections?
Then you should implement it as a Context manager:
class DB:
def __init__(self):
self.dbconn = None
def get_last(self, n)
try:
cur = self.dbconn.cursor()
sqlQuerygetlast = "SELECT * FROM data ORDER BY id DESC LIMIT {}".format(n)
cur.execute(sqlQuerygetlast)
rows = cur.fetchall()
for row in rows:
print(row)
except Exception as e:
print("Exeception occured:{}".format(e))
finally:
# self.dbconn.commit()
def some_other_method(self):
self.dbconn.do_something()
def __enter__(self):
self.dbconn = pymysql.connect(
host='192.168.1.2',
port=3307,
user='username',
passwd='password',
db='dbname'
)
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
dbconn.close()
return True
and use it as follows:
with DB() as db:
db.get_last(1)
db.get_last(10)
db.some_other_method()
This will create only one instance of a database connection and close after it is finished.
Writing a class in Python is fairly simple.
Here's an example of how to write the classic Person class and how to use properties and methods.
Specifically, the presentation method is also making use of the name property.
From this example you can move on and build your Database class implementation quite easily:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def presentation(self):
print("Hello my name is " + self.name)
p1 = Person("John", 36)
p1.presentation()
Remember that in all the methods of a class you will have to specify the reserved keyword self as parameter (plus, clearly, any other parameter you might need).
Python newbie here. I am writing a class that has a method to calculate the distance between 2 sets of coordinates. This methods takes 2 arguments:
Pair of coordinates of a house
Pair of coordinates of a subway station
This is my code:
import pymysql.cursors
class Test(object):
def __init__(self):
self.create_connection()
def create_connection(self):
self.conn = pymysql.connect(host='localhost',
user='root',
password='',
db='testDB',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
self.cursor = self.conn.cursor()
def __del__(self):
self.c_coord()
self.q_coord()
self.calc_dist(cCoord, qCoord)
self.closeDB
def c_coord(self):
sql = "SELECT ID, coordinates from target where coordinates != 'NA'"
self.cursor.execute(sql)
# a dictionary cursor returns every row in the sql statement as a dictionary
cCoord = self.cursor.fetchall()
return cCoord
def q_coord(self):
sql = "SELECT station, coordinates from qSubway"
self.cursor.execute(sql)
qCoord = self.cursor.fetchall()
return qCoord
# return min subway and distance
def calc_dist(self, cCoord, qCoord):
print(cCoord)
print(qCoord)
def closeDB(self):
self.conn.close()
When I run this in python console, this is what I get:
slsu = Test()
slsu.c_coord()
[{'ID': 6221530552, 'coordinates': '40.745300,-73.861100'}, ...
slsu.q_coord()
[{'station': '21st Street (IND Crosstown Line)', 'coordinates': '40.744591, -73.948674'}, ...
slsu.calc_dist(cCoord, qCoord)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'cCoord' is not defined
I need some help understanding this error and how to fix it? I thought if you pass an argument to the function, it should automatically recognize it?
You have to declare the variables cCoord and qCoord. Functions do not return variables that you can use. Think of a function as a black box. It can use variables that you give it, but any changes that it makes will not affect anything outside of that function. The return command just means that if you set a variable equal to c_Coord(), than that variable will have the value(s) that the function returns. To fix this, set variables to both of your Coord functions.
cCoord = c_Coord()
qCoord = q_Coord()
The two functions are both run, and now you can use what they returned outside of those functions.
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.
We're working on a text-based game (MUD) and have hit this roadblock.
The code:
class RoomMove():
def __init__(self):
self.room = 1
self.name = 'Lorinth'
self.moveRooms()
self.updateRoom()
[extra code doesn't matter]
def updateRoom(self):
global c
room = str(self.room)
room = (room)
print room
while room > 0:
c.execute("""SELECT * FROM RoomPlayers where ID=?""", room)
spaceCheck = c.fetchone()
print spaceCheck
counter = 1
if spaceCheck[counter] not in ('', None):
counter += 1
else:
room = self.room
name = self.name
c.execute("""UPDATE RoomPlayers SET '1'=? WHERE ID=?""", (name, room))
conn.commit()
it throws back this error:
c.execute("""SELECT * FROM RoomPlayers where ID=?""", room)
ValueError: parameters are of unsupported type
EDITS: I've tried it with (room, ) ..no difference in the error though.
Any ideas?
Thanks!
As you can read in the documentation:
fetchone()
Fetches the next row of a query result set, returning a single sequence, or None when no more data is available.
If there is no more data c.fetchone() assigns None to the spaceCheck variable, hence TypeError when you try to access spaceCheck[counter].
Try something like that:
if spaceCheck is not None:
counter += 1
UPDATE
You should replace
room = (room)
with:
room = (room, )
Another update
Assuming you create table like below:
sqlite> CREATE TABLE RoomPlayers (ID numeric, player_name VARCHAR);
Your code could like similar to this:
class RoomMove():
def __init__(self, room, name):
self.room = room
self.name = name
self.con = None
self.db_path = "./foo.sqlite"
def updateRoom(self):
try:
# Globals are evil. Don't use them
self.con = sqlite3.connect(self.db_path)
c = con.cursor()
# comparing tuple or string to number dosen't make sense. Compare original number
# You should check if room is valid inside constructor
# while room > 0 would probably lead to indefinite loop
if rooom > 0:
#You don't have to cast room number to string
c.execute("""SELECT id FROM RoomPlayers where ID=?""", (self.room, ))
spaceCheck = c.fetchone()
# Your counter takes only two values so you can do it like that
counter = 2 if spaceCheck is not None else 1
if counter == 1:
# Don't name columns '1' - it is really bad idea
# Like above - coneverting room and name to string is pointlees
c.execute("""UPDATE RoomPlayers SET 'player_name'=? WHERE ID=?""", (self.name, self.room))
self.con.commit()
finally:
# No matter what happens close connection
if self.con is not None:
self.con.close()
What fixed the problem shown above:
sqlite3 doesn't read integers, just strings. (not actually true)
So I made the integer be read as a string in the else loop.
here:
else:
room = self.room
name = self.name
c.execute("""UPDATE RoomPlayers SET '1'=? WHERE ID=?""", (name, room))
room is being passed to c.execute as an integer, the solution?
else:
room = str(self.room)
....
Took forever to see that!