Sql query (with Desc order and Limit) not working on python (OpenERP)
-
21-12-2019 - |
Question
I've been struggling with this issue all day and tried all possible ways that i know.here's the problem:
The field that i'm working on has a format like this:
XXX-year example: 001-2014 (String)
suppose that we have these records:
- 001-2014
- 011-2014
- 013-2013
the result that i expect to get is 011-2014 (in other words the earliest year with the biggest value)
I'v wrote this query that works fine on PostgreSql:
select split_part(numero_bl, '-', 1) as part1,
split_part(numero_bl, '-', 2) as part2
from livraisons
ORDER BY part2 desc,part1 desc limit 1
the split_part function split the column 'numero_bl' to 2 parts.so the result is something like that:
part1| part2
001 | 2014
When i try to introduce it inside Python code it returns correct values using ascending order but returns ('None',) when it comes to descending order
here's a simple version of my function in python:
def set_numero_bl(self, cr, uid, ids,name,arg,context=None):
res={}
cr.execute("""select split_part(numero_bl, '-', 1) as part1,
split_part(numero_bl, '-', 2) as part2
from livraisons
ORDER BY part2 desc,part1 desc limit 1""")
execution = cr.fetchone()
part1 = execution[0]
part2 = execution[1]
if part1:
if part2:
annee = int(part2)
nombre = int(part1)+1
valeur_final= str('%0*d' % (3, nombre))+"-"+str(annee)
for livraisons in self.browse(cr, uid, ids):
res[livraisons.id]= valeur_final
else:
valeur_final= str('%0*d' % (3, 1))+"-"+datetime.datetime.strftime(datetime.datetime.now(), '%Y')
for livraisons in self.browse(cr, uid, ids):
res[livraisons.id]= valeur_final
return res
of course when i won't put the 'else clause' it will return ('None',)
Please is there anyway to fix it or to solve it in any other way?
Thank you
Solution 2
I've found out a way to solve my problem. I changed my query to this
cr.execute("""select max(numero_bl) as part from livraisons
where split_part(numero_bl, '-', 2) >= %s""",
((datetime.datetime.strftime(datetime.datetime.now(), '%Y')),))
First ,I keep only records where the year part is greater than the current year, after that i take the max value of my field 'numero_bl'
here's the full code if anyone is interested:
def set_numero_bl(self, cr, uid, ids,name,arg,context=None):
res={}
cr.execute("""select max(numero_bl) as part
from livraisons
where split_part(numero_bl, '-', 2) >= %s""",
((datetime.datetime.strftime(datetime.datetime.now(), '%Y')),))
valeur = cr.fetchone()[0]
if valeur:
value = valeur.split('-');
nombre = int(value[0])+1
valeur_final= str('%0*d' % (3, nombre))+"-"+datetime.datetime.strftime(datetime.datetime.now(), '%Y')
for livraisons in self.browse(cr, uid, ids):
res[livraisons.id]= valeur_final
else:
valeur_final= str('%0*d' % (3, 1))+"-"+datetime.datetime.strftime(datetime.datetime.now(), '%Y')
for livraisons in self.browse(cr, uid, ids):
res[livraisons.id]= valeur_final
return res
Thank you all for your replies
OTHER TIPS
There are nulls in that column. When you ask for a descending order nulls will come first:
select *
from (values (1), (null)) s(a)
order by a desc;
a
---
1
(2 rows)
If you want to keep nulls then tell it to order nulls last
select *
from (values (1), (null)) s(a)
order by a desc nulls last;
a
---
1
(2 rows)
Or just filter out the nulls
select *
from (values (1), (null)) s(a)
where a is not null
order by a desc;
a
---
1
(1 row)