operator.itemgetter(*item) giving error TypeError: '<' not supported between instances of 'NoneType' and 'int' - sorting

I am using a recursive function for Grouping data list which I am getting by executing database query and the below function worked fine. But since yesterday it started throwing error as below:
in _group_data data_list.sort(key=itemgetter(*filter_key))
TypeError: '<' not supported between instances of 'NoneType' and 'int'
def _group_data(data_list, key_list, previous_key=[]):
"""
:param data_list: A list of dictionary got from executing sql query.
:param key_list: Group by list of keys.
:param previous_key: The earlier key to do grouping at the root level. Default is an empty list.
:return: Grouped Data list.
"""
# Base case
if len(key_list) == 1:
filter_key = key_list[0]
data_list.sort(key=itemgetter(*filter_key))
dl = list()
for _, group in groupby(data_list, key=itemgetter(*filter_key)):
d_dict = {'details': []}
for g in group:
if previous_key is not None:
d_dict['details'].append(
{key: value for key, value in g.items() if key not in (filter_key + previous_key)}
)
d_dict.update({key: value for key, value in g.items() if key in filter_key})
else:
d_dict['details'].append({key: value for key, value in g.items() if key not in filter_key})
d_dict.update({key: value for key, value in g.items() if key in filter_key})
dl.append(d_dict)
return dl
# Recursive block
else:
filter_key = key_list[0]
dl = list()
p_key = previous_key + filter_key
data_list.sort(key=itemgetter(*filter_key)) #getting error here
for _, group in groupby(data_list, key=itemgetter(*filter_key)):
group_list = list(group)
print('key_list[1:] ',key_list[1:])
print('p_key ',p_key)
d_list = _group_data(group_list, key_list[1:], p_key)
p_dict = {key: value for key, value in group_list[0].items() if key in filter_key}
p_dict['details'] = d_list
dl.append(p_dict)
return dl
I am trying to Identify the problem but not getting any clue, Also tried few things from the google search but nothing helped for example sorted() but got the same error. Thanks in advance for the help.

Issue was resolved. I was getting data as null for a key, but it was supposed to be integer that's why it was throwing error. so, from the dB side value of that key is set to 0 as a default.

Related

Ruby - How to filter SQLite rows based on column conditions

I have a variable session[:pet_profile_tags] that returns an array like ["adult", "activity_low", "overweight"].
I then have an SQLite database, called balto.db, which contains the table pet_tips. That table contains 2 columns, "ID" (Integer) and "C1_inclusion" (VARCHAR).
For each row of the pet_tips table, I need to check if the value contained in the C1_inclusion column contains one of the values of the session[:pet_profile_tags] array variable. If that is the case, I need to check the row's ID and store it inside another array variable, named pet_tips.
I tried the below code but I am getting the following error: TypeError - no implicit conversion of String into Integer: index.rb:428:in '[]' , line 428 being if (session[:pet_profile_tags].include?(row["C1_inclusion"].to_s))
# Assign pet tips
pet_tips = []
# Query the pet_tips table
db = SQLite3::Database.open "balto.db"
rows = db.execute("SELECT * FROM pet_tips")
# Iterate through each row of the table
rows.each do |row|
# Check if the row matches the C1_inclusion column
if (session[:pet_profile_tags].include?(row["C1_inclusion"].to_s))
# If the row matches, add the ID to the pet_tips array
pet_tips << row["ID"]
end
end
session[:pet_tips] = pet_tips
db.close
I have been stuck for hours, any help would be really appreciated!
First I tried returning the value of the session[:pet_profile_tags] variable to make sure I was getting the correct array. Then, I made sure to check that the different column and variable names where correctly referenced in my code.
Error
Your error is here: row["C1_inclusion"]
row is an Array of values in column order e.g. [1,"adult"].
Array#[] expects an Integer (index) but you are calling it with a String ("C1_inclusion")
Solutions
To solve this you can
Option 1:
Use Integer indexes based on column order
if (session[:pet_profile_tags].include?(row[1]))
pet_tips << row[0]
end
Option 2: convert the row to Hash:
Always:
db = SQLite3::Database.open "balto.db"
db.results_as_hash
rows = db.execute("SELECT * FROM pet_tips")
rows.each do |row|
if (session[:pet_profile_tags].include?(row["C1_inclusion"]))
Just for this loop:
rows.each_hash do |row|
if (session[:pet_profile_tags].include?(row["C1_inclusion"]))
Option 3: Query just the data you want.
# Query the pet_tips table
db = SQLite3::Database.open "balto.db"
session[:pet_tips] = db.prepare("SELECT ID FROM pet_tips WHERE pet_tips.C1_inclusion IN (?)")
.execute!(session[:pet_profile_tags].map {|s| "'#{s}'"}.join(","))
.flatten
db.close
This uses session[:pet_profile_tags] as a WHERE condition against pet_tips.C1_inclusion and assumes you have control over this variable (e.g. does not perform escaping)

how to use a custom Function in Oracle Statement on each value of one column using Scala

I have a Scala Function. I need to read records that their last two characters of ID column are equal to the result of func. So, I must use func in Oracle query which is in following:
def func(id:String): Int = {
val two_char = id.takeRight(2).toInt
val group_id = two_char % 4
return group_id
}
val query = """ SELECT * FROM table where """+func("ID") + """==="""+group_id
When Scala run the query, I receive this error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "ID"
func pass name of column not its values. Would you please guide me how to use the function in Oracle Query to operate on each value of the column?
Any help is really appreciated.

openerp domain filters how to compare 2 fields in object?

In Odoo/OpenERP I want to make a filter to compare field1 and field2 of the same object like below.
Plz let me know how to make this filter work, adding filter on partners search form:
<field name="credit_limit"/>
<field name="credit"/>
<filter name="credit limit" domain="[('credit','>',credit_limit)]"/>
Applying this filter gives below error:
Uncaught Error: Failed to evaluate search criterions:
{"code":400,"message":"Evaluation Error","data":{"type":"local_exception","debug":"Local evaluation failure\nNameError: name 'credit_limit' is not defined\n\n{\"domains\":[[],\"[('customer','=',1)]\",\"[('credit','=',credit_limit)]\"],\"contexts\":[{\"lang\":\"en_US\",\"tz\":\"Africa/Cairo\",\"uid\":1,\"search_default_customer\":1}],\"group_by_seq\":[]}"}}
I googled many times to find a solution without finding anyone .
the simple form [('credit_limit','<',credit)] always returns the error "can not convert string to float" where string is credit and float is credit_limit.
is there any way to say [('credit_limit','<',valueof(credit))] or [('field1','=',valueof(field2))] ??
Regards,
You need to create a function field with a search function to do that.
Here is an example, using the 'old api' syntax:
class SomeModel(orm.Model):
_name = 'some.model'
def _func_credit_limit_exceeded(self, cr, uid, ids,
field_name, arg, context):
"""compute the value of the function field"""
res = {}
for record in self.browse(cr, uid, ids, context=context):
res[record.id] = record.credit > record.credit_limit
return res
def _func_search_credit_limit_exceeded(self, cr, uid, obj,
name, criterion, context):
"""we only support a search on the form
('column_name', '=', boolean) or ('column_name', '!=', boolean)
"""
match_ids = []
field, op, value = criterion
# argument processing
if op == '!=':
value = not value
elif op != '=':
raise ValueError('Unsupported operator')
# build the search query
if value = True:
comparison = '>'
else:
comparison = '<='
query = 'SELECT id FROM some_model ' \
'WHERE credit %s credit_limit' % comparison
# get the ids matching the search
# and return the corresponding domain
cr.execute(query)
for row in cr.fetchall():
match_ids.append(row[0])
if match_ids:
# return domain matching the selected ids
return [('id', 'in', match_ids)]
else:
# return a domain which will never yield a result
return [('id', '=', 0)]
_columns = {'credit': fields.float('Credit'),
'credit_limit': fields.float('Credit Limit'),
'credit_limit_exceeded':
fields.function(_func_credit_limit_exceeded,
fnct_search=_func_search_credit_limit_exceeded,
string='Credit Limit Exceeded',
type='boolean'),
}
For numeric fields, you can create a computed field which counts the difference of the two field. if the result is 0 they are equal, if negative the 2nd is greater if positive the first is greater.

Unable to create a constant value - only primitive types or Enumeration types allowed

I have seen some questions related to this Exception here but none made me understand the root cause of the problem. So here we have one more...
var testquery =
((from le in context.LoanEMIs.Include("LoanPmnt")
join lp in context.LoanPmnts on le.Id equals lp.LoanEMIId
where lp.PmntDtTm < date && lp.IsPaid == false
&& le.IsActive == true && lp.Amount > 0
select new ObjGetAllPendingPmntDetails
{
Id = lp.Id,
Table = "LoanEMI",
loanEMIId = lp.LoanEMIId,
Name = le.AcHead,
Ref = SqlFunctions.StringConvert((double)le.FreqId),
PmntDtTm = lp.PmntDtTm,
Amount = lp.Amount,
IsDiscard = lp.IsDiscarded,
DiscardRemarks = lp.DiscardRemarks
}).DefaultIfEmpty(ObjNull));
List<ObjGetAllPendingPmntDetails> test = testquery.ToList();
This query gives the following Exception Message -
Unable to create a constant value of type CashVitae.ObjGetAllPendingPmntDetails. Only primitive types or enumeration types are supported in this context.
I got this Exception after I added the SQL function statement to convert le.FreqId which is a byte to a string as ToString() is not recognized in the LINQ Expression Store.
ObjGetAllPendingPmntDetails is a partial class in my model which is added as it is used too many times in the code to bind data to tables.
It has both IDs as long, 'Amount' as decimal, PmntDtTm as Datetime,IsDiscard as bool and remaining all are string including 'Ref'.
I get no results as currently no data satisfies the condition. While trying to handle null, I added DefaultIfEmpty(ObjNull) and ObjNull has all properties initialized as follows.
ObjGetAllPendingPmntDetails ObjNull = new ObjGetAllPendingPmntDetails()
{ Id = 0, Table = "-", loanEMIId = 0, Name = "-", Ref = "-",
PmntDtTm = Convert.ToDateTime("01-01-1900"),
Amount = 0, IsDiscard = false, DiscardRemarks = "" };
I need this query to work fine as it has Union() called on it with 5 other queries. All returning the same ObjGetAllPendingPmntDetails columns. But there is some problem as this query has no data satisfying the conditions and the Exception Shared Above.
Any suggestions are appreciated as I am unable to understand the root cause of the problem.
#AndrewCoonce is right, the .DefaultIfEmpty(ObjNull) is the culprit here. Entity Framework turns DefaultIfEmpty into something like...
CASE WHEN ([Project1].[C1] IS NULL) THEN #param ELSE [Project1].[Value] END AS [C1]
...but there's no way to coerce an instance of ObjGetAllPendingPmntDetails into something that can take the place of #param, so you get an exception.
If you move the DefaultIfEmpty call to after the ToList it should work correctly (although you'll need to call ToList again after that if you really want a concrete list instance).

Linq 2 SQL Sum using lambda and handling nulls

When using sum with lambda in Linq to SQL using the following code:
int query = (from f in odc.RDetails
where f.ticketID == int.Parse(ticket.ToString())
select f).Sum(x => x.Rate);
I get the following error:
The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.
. You have to make sure x.Rate is an int, and not an int? (an int that accepts null as a value).
. If the query has no elements, .Sum won't do anything and will return null. Choose a default value, let's say 0.
var query = from f in odc.RDetails
where f.ticketID == int.Parse(ticket.ToString())
select f;
int result = query.Any()
? query.Sum(x => x.Rate ?? 0) // use the ?? if x.Rate is an "int?".
: 0; // default value you can choose.
I would break the int.Parse(ticket.ToString()) onto its own line to isolate that parse from the Linq for debugging.
We don't know whether that is throwing the exception or if one of the RDetails.Rate values is null. Is it indeed a Nullable<int>?
If RDetails.Rate is a Nullable<int>, then you could ...Sum(x => x.Rate ?? 0) and avoid the exception.

Resources