sqlalchemy and how to count row - python

I have the following code:
query = self.dbObj.session.query(MaterialsTable)
rowCounter = self.dbObj.session.query(MaterialsTable)
for attr , val in interfaceCodesObject.filterNameDict.items():
query = query.filter(and_(getattr(MaterialsTable,attr).like("%%%s%%" % val)))
rowCounter = rowCounter.filter(and_(getattr(MaterialsTable,attr).like("%%%s%%" % val))).count()
query.all()
When i use mutiple field, i get the following traceback:
Traceback (most recent call last):
File "/home/mohsen/codes/amlak/amlak/src/ui/materialsFindFrame.py", line 202, in <lambda>
QtCore.QObject.connect(self.pushButtonSearch, QtCore.SIGNAL(_fromUtf8("clicked()")), lambda: self.interfaceCodesConstructor.responseToRequestForData(self))
File "/home/mohsen/codes/amlak/amlak/src/ui/interface/interface.py", line 109, in responseToRequestForData
self.materialsObejct.findData(self.objectSearchMaterials,self)
File "/home/mohsen/codes/amlak/amlak/src/materials/materials.py", line 133, in findData
rowCounter = rowCounter.filter(and_(getattr(MaterialsTable,attr).like("%%%s%%" % val))).count()
AttributeError: 'long' object has no attribute 'filter'
But when i use just one field it use rowCounter as integer and real return.
My question is , how can i adapt it with multiple field?Such as : Where name = 'barak' and id != 3 But one filed such as : Where name = 'barak'

Do you just want to get the count of final result? In that case, in fact, you just need only one query object instead of both query and rowCounter.
query = self.dbObj.session.query(MaterialsTable)
for attr , val in interfaceCodesObject.filterNameDict.items():
query = query.filter(and_(getattr(MaterialsTable,attr).like("%%%s%%" % val)))
# all result rows
query.all()
# count of rows
rowCounter = query.count()
Hope this helps.

Related

TypeError: 'NoneType' object is not subscriptable in a int object

Here is a function to check the data and update it
div , update are my mongodb collection object
def data_updater(user1_id,code):
device_id = dvi.find_one({"user_id":user1_id},{"_id":0,"user_id":0})["device_id"]
prv_data = update.find_one({"device_id":device_id},{"_id":0,"device_id":0})
prv_date = prv_data["date"]
msg = prv_data["message"]
if prv_date < current_date and msg != code:
x = update.find_one_and_update({"device_id":id,},{"$set":message":code,"date":current_date}})
print(x.acknowledged)
and when I am calling the function it is giving TypeError data_updater(95626,972681)
the error
Traceback (most recent call last):
File line 170, in <module>
data_updater(95626,972681)
File line 71, in data_updater
device_id = dvi.find_one({"user_id":int(user1_id)},{"_id":0,"user_id":0})["device_id"]
TypeError: 'NoneType' object is not subscriptable
I am not able to find any mistake please help
Your context isn't very clear, however, from the error trace as generated it seems that your find_one() function returns None with the arguments as passed and you are trying to access the value for the key device_id. I recommend you refactor your find_one() function or make use of the following code to resolve the issue at hand:
def data_updater(user1_id,code):
try:
device_id = dvi.find_one({"user_id":user1_id},{"_id":0,"user_id":0})["device_id"]
prv_data = update.find_one({"device_id":device_id},{"_id":0,"device_id":0})
prv_date = prv_data["date"]
msg = prv_data["message"]
if prv_date < current_date and msg != code:
x = update.find_one_and_update({"device_id":id,},{"message":code,"date":current_date}})
print(x.acknowledged)
except TypeError:
print('No value found for specified parameters :/')
PS: I also didn't understand the use of $ in your code, so I removed it thinking of it as a mistake. Hope this helps! 😊

How to get value from JSON - Python

If anyone can help me to get a value from a json response. I intend to get only the first incidence of id where the type is CLIENTREF.
I am reading a list to get some values to do a GET and check if the response is other than null "".
This is the JSON structure:
This is my code so far
def checkParent(list):
for item in list:
cdwParenturl = f"http://cdwu/cdw/counterparties/{item}/?yyyy-mm-dd={dateinplay}"
r = requests.get(cdwParenturl).json()
jsonpath_expression = parse("$..identifier[*]")
# $..identifier[?(#.type == 'CLIENTREF')].id
parentId = []
for match in jsonpath_expression.find(r):
# print(f"match id: {match.value}")
thisdict = match.value
if thisdict["type"] == "CLIENTREF":
# print(thisdict["id"])
parentId.append(thisdict["id"])
elif thisdict["id"] == "":
print(colored(f"The parent {item} does not have ultimateParent", "red"))
print(colored(f"All counterparties have parent", "green"))
checkParent(r_mheu_trade)
print(f "match id: {match.value}") I get this, What I need is the first id related to the type: CLIENTREF
The error that appears on my console is this:
Traceback (most recent call last):
File "h:\DESKTOP\test_check\checkCounterpartie.py", line 114, in <module>
checkParent(r_mheu_trade)
File "h:\DESKTOP\test_check\checkCounterpartie.py", line 106, in checkParent
if thisdict["type"] == "CLIENTREF":
KeyError: 'type'
With the help of pyzer I found a solution to my problem. This is how the code looks like:
# Request to get all UltimateParent
def checkParent(murex):
for item in murex:
cdwParenturl = f"http://cdwu/cdw/counterparties/{item}/?yyyy-mm-dd={dateinplay}"
r = requests.get(cdwParenturl).json()
clientref = r[0]["riskUltimateParent"]["identifier"][1]
if clientref == "":
print(colored(f"The parent {item} does not have ultimateParent", "red"))
else:
print(colored(f"All counterparties have parent", "green"))
checkParent(r_mheu_trade)

i inserting data in to a table but raises the error

This is the code
def parse_listings(self, response):
'''
content = ''
with open('incidec1.html', 'r' ) as f:
for line in f.read():
content += line
response = Selector(text=content)
brand = response.css('div[class="fs21"]').css('span').css('a::text').get()
title = response.css('div[class="klavikab lilac"]').css('span::text').get()
t = (id, brand,title)
cur.execute('''INSERT INTO products VALUES(%s,%s,%s,%s,%s)''',(id, brand, title))
mydb.commit()
print('complete.')
if __name__ == '__main__':
incidecoderspider.parse_listings(incidecoderspider,'')'
this the output error:
Traceback (most recent call last):
File "incidecoder1.py", line 98, in <module>
incidecoderspider.parse_listings(incidecoderspider,'')
File "incidecoder1.py", line 80, in parse_listings
cur.execute('''INSERT INTO products VALUES(%s,%s,%s,%s,%s)''',(id, brand, title, photo, ingredients))
AttributeError: 'builtin_function_or_method' object has no attribute 'translate'
i tried very much but can't understanfd what is the problem.
You're trying to use a value that you didn't define: id. Normally, this would get you an "undefined symbol" error. However, id is defined: it's a built-in function.
Simply change the variable name so that you don't collide with a built-in item (such as product_id), and then give that variable a value.

TypeError: 'int' object is not subscriptable Where is int?

I got an error,TypeError: 'int' object is not subscriptable .
I wanna connect 2 excel data
to User model.
So my ideal output is
1|1|Blear|40|false|l|America|A|1
2|5|Tom|23|true|o|UK|A|3
3|9|Rose|52|false|m
4|10|Karen||||Singapore|C|2
For example,Rose data of user_id=3 is not in second excel, in that case being 2nd data empty is ok.I am thinking putting 2nd excel in dictionary type to User model.
I searched the errors I thought this part for data in data_dict was wrong, I changed it into for data in range(len(data_dict)) but same error happens.I really cannot understand where is wrong.How should I fix this?
Now views.py is
#coding:utf-8
from django.shortcuts import render
import xlrd
from .models import User
book = xlrd.open_workbook('../data/excel1.xlsx')
sheet = book.sheet_by_index(1)
def build_employee(employee):
if employee == 'leader':
return 'l'
if employee == 'manager':
return 'm'
if employee == 'others':
return 'o'
for row_index in range(sheet.nrows):
rows = sheet.row_values(row_index)
is_man = rows[4] != ""
emp = build_employee(rows[5])
user = User(user_id=rows[1], name_id=rows[2], name=rows[3],
age=rows[4],man=is_man,employee=emp)
user.save()
book2 = xlrd.open_workbook('../data/excel2.xlsx')
sheet2 = book2.sheet_by_index(0)
headers = sheet2.row_values(0)
large_item = None
data_dict = {}
for row_index in range(sheet2.nrows):
rows2 = sheet2.row_values(row_index)
large_item = rows2[1] or large_item
# Create dict with headers and row values
row_data = {}
for idx_col, value in enumerate(rows2):
header_value = headers[idx_col]
# Avoid to add empty column. A column in your example
if header_value:
row_data[headers[idx_col]] = value
# Add row_data to your data_dict with
data_dict[row_index] = row_data
for row_number, row_data in data_dict.items():
user1 = User.objects.filter(user_id = data['user_id']).exists()
if user1:
user1.__dict__.update(**data_dict)
user1.save()
Now Traceback is
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/XXX/testapp/app/views.py", line 123, in <module>
user1 = User.objects.filter(user_id = row_data['user_id']).exists()
KeyError: 'user_id'
data is an integer. So calling data like a dict raises that expection.
>>> a=1
>>> a['a']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not subscriptable
Why is it an int ? Because you're iterating over data's keys:
>>> a={1: 'x', 2: 'c'}
>>> for i in a: print(i)
...
1
2
Try using items() as such:
>>> for key, value in a.items(): print(key, value)
...
1 x
2 c
Or, in your specific case:
for row_number, row_data in data_dict.items():
print(row_number, row_data)
See looping techniques for dict documentation for details.

Why peewee coerces select column to integer

I can't use sqlite function group_concat() in peewee. Here is complete snipet. Somehow peewee want to convert result of group_concat() to integer, while it is string ("1,2"). I can't find the way to suppress it.
from peewee import *
db = SqliteDatabase(':memory:')
class Test(Model):
name = CharField()
score = IntegerField()
class Meta:
database = db
db.create_tables([Test])
Test.create(name='A', score=1).save()
Test.create(name='A', score=2).save()
#select name, group_concat(score) from Test group by name
for t in Test.select(Test.name, fn.group_concat(Test.score)).order_by(Test.name):
pass
It produces following error:
Traceback (most recent call last):
File "C:\Users\u_tem0m\Dropbox\Wrk\sgo\broken.py", line 17, in <module>
for t in Test.select(Test.name, fn.group_concat(Test.score)).order_by(Test.name):
File "C:\Program Files\Python 3.5\lib\site-packages\peewee.py", line 1938, in next
obj = self.qrw.iterate()
File "C:\Program Files\Python 3.5\lib\site-packages\peewee.py", line 1995, in iterate
return self.process_row(row)
File "C:\Program Files\Python 3.5\lib\site-packages\peewee.py", line 2070, in process_row
setattr(instance, column, func(row[i]))
File "C:\Program Files\Python 3.5\lib\site-packages\peewee.py", line 874, in python_value
return value if value is None else self.coerce(value)
ValueError: invalid literal for int() with base 10: '1,2'
Try adding a coerce(False) to your call to group_concat:
query = (Test
.select(Test.name, fn.GROUP_CONCAT(Test.score).coerce(False))
.order_by(Test.name))
for t in query:
pass
Peewee sees that Test.score is an integer field, so whenever a function is called on that column, Peewee will try to convert the result back to an int. The problem is that group_concat returns a string, so we must tell Peewee not to mess with the return value.
Just found what result of fn.group_concat(""+Test.score) don't cast to integer. But I think resulting sql maybe less optimal
SELECT "t1"."name", group_concat(? + "t1"."score") AS allscore FROM "test" AS t1 ORDER BY "t1"."name" ['']
Do anybody knows more elegant way?

Categories