python mysql select in class - mysql

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)

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)

How to get column names from a SQL query?

I need to put data from the SQL query into a Pandas dataframe. Please tell me is it possible to get column names the query results? I found that there is a keys() function in sqlalchemy for that but it does not work for me:
import mysql.connector
import pandas as pd
mydb = mysql.connector.connect(
host="SQLServer",
user="sqlusr",
password="usrpasswd",
database="sqldb"
)
cursor = mydb.cursor()
Query="SELECT Title, Review, Rate FROM reviews;"
cursor.execute(Query)
df = pd.DataFrame(cursor.fetchall())
df.columns = cursor.keys()
AttributeError: 'CMySQLCursor' object has no attribute 'keys'
I think that it your are searching for
cnx = mysql.connector.connect(user=DB_USER, password=DB_USER_PASSWORD, host=DB_HOST, database=DB_NAME)
cursor = cnx.cursor()
query = ("SELECT `name`, `ftp_name`, `created_at`, `status` AS `status_customer` FROM `customers"
"WHERE `status` = %(status)s")
cursor.execute(query, { 'status': 1 })
# cursor.description will give you a tuple of tuples where [0] for each is the column header.
num_fields = len(cursor.description)
field_names = [i[0] for i in cursor.description]
print(num_fields)
print(field_names)
>>> 4
>>> [u'name', u'ftp_name', 'created_at', u'status_customer']
# OR just use this cursor function:
print(cursor.column_names)
>>> (u'name', u'ftp_name', 'created_at', u'status_customer')
Hope this helps!
SHOW COLUMNS FROM your-database-name.your-table-name

Could not perform concurrent requests from mysql db through django ; InterfaceError at url (0, '')

I've a django app which fetches data from mysql db whenever a request is received.This works fine when request is processed by one user but, when more than user send request, I get a error message saying "InterfaceError at url (0, '')".
I'm using Django version 1.9.
As per my research , I included CONN_MAX_AGE in my settings.py but still I got the same error.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
**'CONN_MAX_AGE': None**
}
}
my models.py
connection = pymysql.connect(host='localhost',user='user',password='password',db='db_name',port=3306,charset='utf8',cursorclass=pymysql.cursors.DictCursor)
def execute(query):
cur = connection.cursor()
cur.execute(query)
data = cur.fetchall()
connection.commit()
cur.close()
return data
def trending_assets():
sql = "select * from media_recommendation_engine.content_table t1 inner join (SELECT movieId,rank from" \
" media_recommendation_engine.asset_ranks limit 10) t2 on t1.movieId = " \
"t2.movieId order by t2.rank asc ;;"
data = execute(sql)
return data
views.py
#permission_classes((permissions.IsAuthenticated,))
class Trending(viewsets.GenericViewSet):
def list(self,request):
if request.query_params['type']=='trending':
result_data = models.trending_assets()
return Response(models.formatter(result_data))
#
else:
return JsonResponse({'message': 'Wrong Argument pass'},status= 400)
You should connect the db each time you need to when a request need to be processed. Earlier I used a connection globally. And do not use db.close().
def execute(query):
connection = pymysql.connect(host='localhost', user='user', password='passsword', db='db_name', port=3306, charset='utf8', cursorclass=pymysql.cursors.DictCursor)
cur = connection.cursor()
cur.execute(query)
data = cur.fetchall()
connection.commit()
cur.close()
return data
def trending_assets():
sql = "select * from media_recommendation_engine.content_table t1 inner join (SELECT movieId,rank from" \
" media_recommendation_engine.asset_ranks limit 10) t2 on t1.movieId = " \
"t2.movieId order by t2.rank asc ;;"
data = execute(sql)
return data

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))

A Properly Formated Mysql Query for Python

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):