A Properly Formated Mysql Query for Python - mysql

I'm struggling with the formatting on a mysql query and I was hoping you could point me in the right direction. Here are the queries
sql = "SELECT price FROM inventory WHERE card_name = %s AND card_set = %s"
sql_rare = "SELECT rarity FROM inventory WHERE card_name = %s AND card_set = %s"
sql_count = "SELECT count(*) FROM inventory WHERE card_name = %s AND card_set = %s
When I run the following code, utilizing the sql_count query, i get an error saying:
File "C:\Users\Spencer\Desktop\Python Programs\PythonMTG\Revision3AutoAndManual\51515\magicassistantcsv.py", line 264, in output_card
for row in getmtgprice.query(sql_count, ([card_name, set_name])):
TypeError: query() takes exactly 4 arguments (3 given)
Here is the code producing this error:
getmtgprice = PriceCheck()
for row in getmtgprice.query(sql_count, ([card_name, set_name])):
if row[0] ==0:
priced_card = '0.00'
And here is the PriceCheck function:
class PriceCheck(object):
def __init__(self):
self.conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='mscan')
self.c = self.conn.cursor()
def query(self, arg, cardname, setname):
self.c.execute(arg, cardname, setname)
return self.c
def __del__(self):
self.conn.close()
Do you see where I went wrong?

Your query method takes separate arguments for cardname and setname, not a list containing both. So, instead of:
for row in getmtgprice.query(sql_count, ([card_name, set_name])):
You should have:
for row in getmtgprice.query(sql_count, card_name, set_name):

Related

variable not interpolating for Mysql query with flask

I have the following code where the ph variable does not interpolates with the select query.
I am just trying to access http://localhost/testing?phone_number=1234567890 it returns like () rather particular record of the phone number.
#app.route("/testing",methods=['GET')
def testing():
ph = request.args.get('phone_number')
cur = mysql.connection.cursor()
cur.execute('''SELECT * FROM client_base where phone_number={}'''.format(ph))
results = cur.fetchall()
return ''' {} '''.format(results)
Abetter solution is using prepared statements like below
#app.route("/testing",methods=['GET')
def testing():
ph = request.args.get('phone_number')
cur = mysql.connection.cursor()
cur.execute('''SELECT * FROM client_base where phone_number=%s''',(ph,))
results = cur.fetchall()
return ''' {} '''.format(results)

Cannot add records to a mysql database

I have defined a function to add rows to a MYSQL database. But it keeps giving an error saying-
_mysql_connector.MySQLInterfaceError: Column count doesn't match value count at row 1
During handling of the above exception, another exception occurred:
mysql.connector.errors.DataError: 1136 (21S01): Column count doesn't match value count at row 1
Here's my code
#add new records
def add_records():
db = msq.connect(host = "localhost", user = "root", passwd = "abhi2004", database = "Movie_Sites")
cur = db.cursor()
count = int(input("Enter number of records to enter: "))
for i in range(count):
name = input("Enter name of movie: ")
actors = input("Enter a comma separated list of actors: ")
genre = input("Enter genre: ")
ratings = float(input("Enter movie ratings: "))
sql = "insert into movies(Movie,Actors,Genre,Ratings) values ({},{},{},{})".format(name,actors,genre,ratings)
cur.execute(sql)
db.commit()
db.close()
print("Records added")
How do I fix it? What's going wrong?

python mysql select in class

Unfortunately I've no Idea what's the issue coding in this way. I try to run a select statement within a class - the result is: TypeError: open_select() missing 1 required positional argument: 'query'.
Does anybody have an idea? Thx in advance
class finDB_exec:
def __init__(self):
self.dbcn = db.connect(host='localhost',
user='root',
password='xxx',
database='xxxx')
self.dbcr = self.dbcn.cursor()
def db_commit(self):
self.dbcn.commit()
def db_close(self):
self.dbcr.close()
self.dbcn.close()
##############################################################################
#### 1) Open Select
##############################################################################
def open_select(self,query):
try:
self.cr = self.dbcr()
self.cr.execute(query)
self.db_commit()
result = self.cursor.fetchall()
return result
except:
pass
query = 'Select * from tbl_companies limit 10'
res = finDB_exec.open_select(query)

Generate n-gram for a specific column present in mysql db

I'm writing a code to generate n-grams for every record in the table by reading a specific column.
def extract_from_db(inp_cust_id):
sql_db = TatDBHelper()
t_sql = "select notes from raw_data where customer_id = {0}"
db_data = sql_db.execute_read(t_sql.format(inp_cust_id))
for row in db_data:
text = row.values()
bi_grams = generate_ngrams(text[0].encode("utf-8"), 2)
print bi_grams
def generate_ngrams(sentence, n):
sentence = sentence.lower()
sentence = re.sub(r'[^a-zA-Z0-9\s]', ' ', sentence)
tokens = [token for token in sentence.split(" ") if token != ""]
ngrams = zip(*[tokens[i:] for i in range(n)])
return [" ".join(ngram) for ngram in ngrams]
I'm getting the output like:
['i highly', 'highly recommend', 'recommend it']
['the penguin', 'penguin encounter', 'encounter was', 'was awesome']
I want the output to look like below, can anybody help me to get this.
['i highly',
'highly recommend',
'recommend it',
...
]
creat another list all_ngrams, and keep appending the values to it , using .extend(), and finally you will have all the ngrams in one list.
Try this :
def extract_from_db(inp_cust_id):
sql_db = TatDBHelper()
t_sql = "select notes from raw_data where customer_id = {0}"
db_data = sql_db.execute_read(t_sql.format(inp_cust_id))
all_ngrams = []
for row in db_data:
text = row.values()
bi_grams = generate_ngrams(text[0].encode("utf-8"), 2)
all_ngrams.extend(bi_grams)
print all_ngrams

Django annotation output_field=DecimalField ignores max_digits and decimal_places

Inside an annotation I do some calculations, and I want the output to be a decimal, with max 8 digits and max 2 decimal. I don't know why but Django ignores decimal_places and max_digits.
Here is my code:
Order.objects.all().annotate(
amount=Coalesce(
Sum(
Case(
When(
Q(payments__status='complete'),
then=F('payments__amount') - (
F('payments__amount') * F('payments__vat')/100
)
), output_field=DecimalField(decimal_places=2, max_digits=8)
)
), 0)
).values('amount')
output = 12.5999999999999996447286321199499070644378662109375
I'm using Django 1.9.5
I had had the same issue in my job, to solve this I've created the following custom aggregate:
class SumDecimal(Func):
function = 'SUM'
name = 'sum'
contains_aggregate = True
output_field = DecimalField()
template = '%(function)s(%(expressions)s)'
def __init__(self, *args, **kwargs):
self.decimal_places = kwargs.pop('decimal_places', None)
super(SumDecimal, self).__init__(*args, **kwargs)
def as_sql(self, compiler, connection, function=None, template=None):
sql = super(SumDecimal, self).as_sql(
compiler=compiler,
connection=connection,
function=function,
template=template)
if self.decimal_places:
sql, params = sql
sql = 'CAST(%s AS DECIMAL(16, %d))' % (sql, self.decimal_places)
return sql, params
return sql
To use this is pretty simple, just use like:
mymodel.objects.all().annotate(sum_value=SumDecimal('value', decimal_places=2))