This Python class is supposed to query an SQLite database:
import sqlite3
class Database:
def __init__(self):
self.connection = sqlite3.connect('devel.db')
self.cursor = self.connection.cursor()
self.connection.commit()
def query(self, query, params=()):
if params == ():
self.cursor.execute(query)
else:
self.cursor.execute(query, params)
self.connection.commit()
return True
def select(self, query, params=()):
if params == ():
self.cursor.execute(query)
else:
self.cursor.execute(query, params)
return self.cursor.fetchall()
id = 1
Database.select("SELECT * FROM users WHERE id = ?", (id,))
It gives :
AttributeError: 'str' object has no attribute 'cursor'
I also tried self.connection.cursor() instead of self.cursor.
To call the query method, you need to first create an instance of the Database class.
Basically, by calling the query method without an object, you are passing the query string as the self parameter, so it tries to access the cursor() method in a string and not the class itself.
So instead of executing this code:
Database.select("SELECT * FROM users WHERE id = ?", (id,))
You need to do something like this:
db = Database()
db.select("SELECT * FROM users WHERE id = ?", (id,))
Related
I'm using python 3.5.2 for my project. I installed MySQLdb via pip for Mysql connection.
Code:
import MySQLdb
class DB:
def __init__(self):
self.con = MySQLdb.connect(host="127.0.0.1", user="*", passwd="*", db="*")
self.cur = self.con.cursor()
def query(self, q):
r = self.cur.execute(q)
return r
def test():
db = DB()
result = db.query('SELECT id, name FROM test')
return print(result)
def test1():
db = DB()
result = db.query('SELECT id, name FROM test').fetchall()
for res in result:
id, name = res
print(id, name)
test()
test1()
#test output >>> '3'
#test1 output >>> AttributeError: 'int' object has no attribute 'fetchall'
Test table:
id | name
1 | 'test'
2 | 'test2'
3 | 'test3'
Please read this link:http://mysql-python.sourceforge.net/MySQLdb.html
At this point your query has been executed and you need to get the
results. You have two options:
r=db.store_result()
...or... r=db.use_result() Both methods return a result object. What's the difference? store_result() returns the entire result set to
the client immediately. If your result set is really large, this could
be a problem. One way around this is to add a LIMIT clause to your
query, to limit the number of rows returned. The other is to use
use_result(), which keeps the result set in the server and sends it
row-by-row when you fetch. This does, however, tie up server
resources, and it ties up the connection: You cannot do any more
queries until you have fetched all the rows. Generally I recommend
using store_result() unless your result set is really huge and you
can't use LIMIT for some reason.
def test1():
db = DB()
db.query('SELECT id, name FROM test')
result = db.cur.fetchall()
for res in result:
id, name = res
print(id, name)
cursor.execute() will return the number of rows modified or retrieved, just like in PHP. Have you tried to return the fetchall() like so?
def query(self, q):
r = self.cur.execute(q).fetchall()
return r
See here for more documentation: https://ianhowson.com/blog/a-quick-guide-to-using-mysql-in-python/
import sqlite3, time, datetime, random, random
class DatabaseManager(object):
def __init__(self, db):
self.conn = sqlite3.connect(db)
self.conn.execute('pragma foreign_keys = on')
self.conn.commit()
self.c = self.conn.cursor()
def query(self, arg):
self.c.execute(arg)
self.conn.commit()
return self.c
def fetch(self):
self.c.fetchall()
self.conn.commit()
return self.c
def __del__(self):
self.conn.close()
dbmgr = DatabaseManager("connect.db")
while 1 > 0:
def quantity():
x = 1
file = open("john.txt", "r")
for line in file:
x = random.randint(100,10000000)
func = "INSERT INTO test (playerNAME) VALUES (?, ?)", line, x
dbmgr.query(func)
You can ignore the while 1 > 0, that was part of the code I deleted to specifically ask my question. When I call the function quantity() (in another part of code I also deleted for the questions sake), I get an error that states:
Traceback (most recent call last):
File "C:\Users\senarsky.CAL\Documents\2016Sem2\Sqlite-connect.py", line 210, in
quantity()
File "C:\Users\senarsky.CAL\Documents\2016Sem2\Sqlite-connect.py", line 68, in quantity
dbmgr.query(func)
File "C:\Users\senarsky.CAL\Documents\2016Sem2\Sqlite-connect.py", line 14, in query
self.c.execute(arg)
ValueError: operation parameter must be str
I am not sure how to make the func line a string without using insecure sql formatting...
Enclose your query parameters in a tuple:
query = "INSERT INTO test (playerNAME) VALUES (?, ?)"
parameters = (line, x)
Modify the query method to accept both query and parameters:
def query(self, query, params=None):
self.c.execute(query, params)
self.conn.commit()
return self.c
And then call as:
dbmgr.query(query, parameters)
I'm making a form which allows me to add questions to a database. I've written code but when I try it I get this error ('AttributeError: 'module' object has no attribute 'GetTable')
The error lies with this part of my code 't = self.dbu.GetTable()'
#QtCore.pyqtSignature("on_add_btn_clicked()")
def Add_btn(self):
Question = self.Question_lineEdit.text()#Grabs the text from all line edit fields
Answer = self.Answer_lineEdit.text()
IsmultiChoice = self.IsMultiChoice_lineEdit.text()
if not Question:
QtGui.QMessageBox.warning(self, 'Warning', 'Username Missing')
else:
t = self.dbu.GetTable()
print (t)
for col in t:
if Question == col[1]:
QtGui.QMessageBox.warning(self, 'Warning', 'Question Taken. :(')#Checks the database and warns if the database does exist
else:
self.dbu.AddEntryToTable (Question, Answer, isMultiChoice)
QtGui.QMessageBox.information(self, 'Success', 'User Added Successfully!')#If everythings is okay it adds the user
self.close()
Here is my database code:
import mysql.connector
from mysql.connector import errorcode
from datetime import datetime
class DatabaseUtility:
def __init__(self, database, Tablename,):
self.db = database
self.Tablename = Tablename
self.cnx = mysql.connector.connect(user = 'root',
password = '',
host = 'localhost')
self.cursor = self.cnx.cursor()
def ConnectToDatabase(self):
try:
self.cnx.database = self.db
except mysql.connector.Error as err:
if err.errno == errorcode.ER_BAD_DB_ERROR:
self.CreateDatabase()
self.cnx.database = self.db
else:
print(err.msg)
def CreateDatabase(self):
try:
self.RunCommand("CREATE DATABASE %s DEFAULT CHARACTER SET 'utf8';" %self.db)
except mysql.connector.Error as err:
print("Failed creating database: {}".format(err))
def GetTable(self):
self.Tablename()
return self.RunCommand("SELECT * FROM %s;" % self.Tablename)
def GetColumns(self):
return self.RunCommand("SHOW COLUMNS FROM %s;" % self.Tablename)
def RunCommand(self, cmd):
print ("RUNNING COMMAND: " + cmd)
try:
self.cursor.execute(cmd)
except mysql.connector.Error as err:
print ('ERROR MESSAGE: ' + str(err.msg))
print ('WITH ' + cmd)
try:
msg = self.cursor.fetchall()
except:
msg = self.cursor.fetchone()
return msg
def AddEntryToTable(self, Question, Answer,IsMultiChoice):
cmd = " INSERT INTO " + self.Tablename + " (Question, Answer, IsMultiChoice)"
cmd += " VALUES ('%s', '%s', '%s');" % (Question, Answer, IsMultiChoice)
self.RunCommand(cmd)
def __del__(self):#Deconstructer class
self.cnx.commit()
self.cursor.close()
self.cnx.close()
if __name__ == '__main__':
db = 'UsernamePassword_DB'
Tablename = 'questiontable'
dbu = DatabaseUtility(db, Tablename)
What am I doing wrong and how can I correct it?
I'd need to see some additional code to be sure (see my comment). But for now my guess is it has to do with how you first instantiate or reference the dbu variable/attribute. If all you did is import it from another file, because dbu is created in that file's main() (in the snippet you provided), that might be the issue. For example, this is incorrect:
from whatever import dbu # wrong
from whatever.main import dbu # Also wrong. In fact I don't think this would even work
Instead, import DatabaseUtility directly into the script, then instantiate dbu like :
from whatever import Database Utility
class SomeClass(object):
...
def startDB(self, db, Tablename):
self.dbu = DatabaseUtility(db, Tablename)
The reason I guess this is because the error message says module has no attribute, instead of mentioning the actual class. Here's an example of the error I would expect to see:
In [31]: class MyClass(object):
one = 1
....:
In [32]: myc = MyClass()
In [33]: myc.one
Out[33]: 1
In [34]: myc.two
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-34-4bae87671838> in <module>()
----> 1 myc.two
AttributeError: 'MyClass' object has no attribute 'two'
Notice how it says MyClass is the problem, not "module".
Potentially unrelated, you might want to remove self.Tablename() from DatabaseUtility.GetTable(). The way you have your class defined, Table is an attribute to the DatabaseUtility class, but by including the parentheses you're trying to call it as if it were a method (like GetTable is).
I am attempting to query a SQL Server 2012 database using the following code:
import pyodbc
class sqlserverConnector:
def __init__(self, connectionString):
"""
this is a typical connection string using windows authentication and the DSN manager:
'DSN=python;Trusted_Connection=yes'
"""
self._conn = pyodbc.connect(connectionString)
self._curs = self._conn.cursor()
self.fetchall = self._curs.fetchall
self.description = self._curs.description
self.columns = dict()
def __del__(self):
self._conn.close()
def __iter__(self):
return self._curs.__iter__()
# executes SQL statements
def execute(self, statement, **params):
if params is None:
self._curs.execute(statement)
else:
self._curs.execute(statement,params)
# creates a dictionary of column names and positions
if self._curs.description != None:
self.columns = dict((field[0], pos) for pos, field in enumerate(self._curs.description))
else:
None
And:
from sqlutil import *
sqlcnxn = sqlserverConnector('DSN=python;Trusted_Connection=yes')
rows = sqlcnxn.execute("select * from demographics", params=None)
for row in rows:
print row
break
The goal is to print out a single row (the table has 80k+ rows). However I always get this error message:
pyodbc.ProgrammingError: ('The SQL contains 0 parameter markers, but 1 parameters were supplied', 'HY000')
I have googled around and it seems like this pops up for different people for different reasons and none of the solutions I have found fit my error. I think what is happening is that the execute method is defaulting to the first else statement instead of the first if statement.
When you use the **params notation, then params is always a dictionary.
Calling that function with params=None means you now have a dictionary with:
>>> def func(**params):
... print params
...
>>> func()
{}
>>> func(params=None)
{'params': None}
>>> func(foo='bar')
{'foo': 'bar'}
The syntax is meant to accept arbitrary keyword parameters, illustrated by the foo keyword argument above.
Either remove the ** or test for an empty dictionary, and don't set params=None when calling .execute():
def execute(self, statement, **params):
if not params:
self._curs.execute(statement)
else:
self._curs.execute(statement, params)
# ...
and:
rows = sqlcnxn.execute("select * from demographics")
Note that your execute() function has no return statement, which means that rows will be set to None (the default return value for functions). Add return self if you meant to return the connection object so that it can be iterated over.
i have query like this
query = Notification.query(db.func.count(Notification.id))
query = query.filter(Notification.read == False)
query = query.filter(Notification.id == recv_id)
return query.all()
and i got error like this
query = Notification.query(db.func.count(Notification.id))
TypeError: 'BaseQuery' object is not callable
please help, thanks
Your first line raises the error. query is an instance of BaseQuery and its not callable.
What you are trying to do is similar to:
class A(object):
pass
a_obj = A()
print a_obj()
You can't call an instance.
You should call some method on the instance.
Not sure why you require the first line in your code.
You can do something like:
Notification.query.filter(Notification.read == False)