Genesis Shards Community
hi, good morning, with traslater it`s sql to pony:
select sum(cantidad) as vtotalcantidad from opermv
where tipodoc = vtipodoc
and serie = vserie
and documento = vdocumento
and codigo in(select codigo from bonifidet where idbonifica = '00001');
Alexander
Something like
select(sum(x.a) for x in X if x.b == param1 and x.c == param2 and x.d in select(y.foo for y in Y))
Genesis Shards Community
Pistol
Hey Good Evening. I've a bit of a complex problem I've found and need some guidance how to work out where the problem is and how to resolve. I'll write up a summary, and then create a Google doc with the evidence. As it's quite a subtle problem involving an array of integers...
Volbil
Pistol
OK, there's a Telegram BOT. EmojiBOT, that uses python3, Pony and postgresql. It creates a table to store chat details, including Telegram IDS. The class definition, for this 'administrators' field is an array of Integers, and the converter makes an array of type integers in postgre. BUT, the Telegram ID IS also a BIGINT. When, this ID is written into the array , and then the column in the table, the postgres DB returns an error 'Integer out of range'. I think the problem is that the array is created with type Integer and not bigint. As python only has type int, I've tried to see where and how I can make the type for the column in the table be created with type bigint[] and not integer[]. It's taken me a week of trawling through all the EmojiBOT code, and pony code, and also testing the database etc to find this. Which ,I'll detail ina word doc with annotated screen shots.
Pistol
Sorry for the wall of text!
Volbil
OK, there's a Telegram BOT. EmojiBOT, that uses python3, Pony and postgresql. It creates a table to store chat details, including Telegram IDS. The class definition, for this 'administrators' field is an array of Integers, and the converter makes an array of type integers in postgre. BUT, the Telegram ID IS also a BIGINT. When, this ID is written into the array , and then the column in the table, the postgres DB returns an error 'Integer out of range'. I think the problem is that the array is created with type Integer and not bigint. As python only has type int, I've tried to see where and how I can make the type for the column in the table be created with type bigint[] and not integer[]. It's taken me a week of trawling through all the EmojiBOT code, and pony code, and also testing the database etc to find this. Which ,I'll detail ina word doc with annotated screen shots.
Why use array though?
Volbil
Set seams much more resonable here
Volbil
Pony will handle that for you
Pistol
The field in the table is called administrators , and is an array of all the IDs of admins in a telegram chat.
Pistol
The code was written by someone else and is quite complex , so not sure where 'set' would apply , or even what it means.
Volbil
To clarify, this bot uses Pony ORM, right?
Pistol
Let me do the doc, and that will explain better... with more contex
Volbil
class ChatAdmin(db.Entity):
telegram_id = orm.Required(int)
chat = orm.Required("Chat")
class Chat(db.Entity):
name = orm.Required(str)
admins = orm.Set("ChatAdmin")
Volbil
It would work same way as array does and would require minimal code change
Pistol
Yes it does.. check out Fumaz,EmojiCaptchaBot on github. Goto src/db/models.py then down to line 204 and class Chat ... look for line 217 administrators ..
Volbil
OK, there's a Telegram BOT. EmojiBOT, that uses python3, Pony and postgresql. It creates a table to store chat details, including Telegram IDS. The class definition, for this 'administrators' field is an array of Integers, and the converter makes an array of type integers in postgre. BUT, the Telegram ID IS also a BIGINT. When, this ID is written into the array , and then the column in the table, the postgres DB returns an error 'Integer out of range'. I think the problem is that the array is created with type Integer and not bigint. As python only has type int, I've tried to see where and how I can make the type for the column in the table be created with type bigint[] and not integer[]. It's taken me a week of trawling through all the EmojiBOT code, and pony code, and also testing the database etc to find this. Which ,I'll detail ina word doc with annotated screen shots.
Volbil
Maybe this would help
Volbil
https://docs.ponyorm.org/api_reference.html?highlight=64#cmdoption-arg-size
Pistol
I've tried setting everything to that , and even replaced the word Integer with BIGINT in all code...
Volbil
Have you updated db itself?
Volbil
I mean if it's already created, you have to update type manually
Pistol
I actually loaded the modified py files into docker before the BOT started and created the DB.
Volbil
If you use Postgres, try connecting to db and updating column type manually
Volbil
https://www.postgresqltutorial.com/postgresql-change-column-type/
Pistol
Let me just show the flow quickly.. Line 217 in the models.py defines administrators = Required(IntArray, default[]) ...
Pistol
Let me look at that change..
Pistol
Then ormtypes.py line 394 says class IntArray(Array): item_type = int.
Pistol
So how does the postgres.py code in the dBproviders then know how to create the array with the right integer type... can that line 394, also include a size=64, to allow the field to be BIGINT. ?
Pistol
Thank-you Volibil for your suggestions , help and insights:)
Volbil
:)
Pistol
Can the code to make the integer array also use the PGIntConverter in postgres.py to make the column type.
Pistol
Let me try the changing ofnthe column type... first
Pistol
Can I use Pony ORM to make the change.. ? If so how ?
Pistol
I'm going to sleep now, and will check tomorrow, but if you could think about the array type , as discussed above that would be great !! :)
Volbil
Volbil
Database migration tool is still in development
Pistol
OK hmmm I'll look at what I can do to execute an sql command right after dB creation to change the field type
Alexander
Little spoiler. Change Array type to Set(...) lead to
1. Create new
2. Move data
3. Delete old
Pistol
Thanks for the suggestion ..
Alexander
Ah. I think you don't really need arrays for this case.
One of big problem we met while developing array support was misunderstanding of this type.
I suggest you to have a link to another entity of admin.
What I meant by those 3 steps is - 'How do you change this type to new one'.
In migration tool it will require 3 migrations which I described like steps.
Volbil
Volbil
Using Set would be much more reliable solution compared to arrays
Pistol
OK, remember this isn't my code , so I'm reverse engineering this to try to fix
Pistol
I'll lookup what you've suggested and try some things ..
Pistol
Thanks guys !
Pistol
Hey guys FYI. I just connected to the DB and manually issued the ALTER command which worked !!! After a week of debugging , this helped... but now i need that column type set as bigint[] to start with.... I'll also look the Set thing.tomorrow .. Is there a way I can edit one of the pony Orm files to make all integer arrays to be of type bigint[] when initialising a Table column on the DB, instead of integer[] .. Just a thought for a hack..
Pistol
Thanks for the suggestion on the Alter table !! Huzzah :)
Alexander
@THEPistolPete_PQ_Onboard you should be able to explicitly specify the sql_type value for the attribute:
some_array = Required(IntArray, sql_type="bigint[]")
Pistol
Brilliant let me try that somewhere
Pistol
Good morning
Pistol
Would that be in the class definition
Alexander
yes
Pistol
The current line is
Pistol
administrators = Required(IntArray , default []) , so should I change rhe default[] or add eg Required(IntArray, default[], sql_type="bigint[]")
Pistol
It worked
Pistol
@metaprogrammer , Thankyou so much , that simple line addition has solved, what has been a tortuous 7 days of deep troubleshooting. That said, my knowledge of docker, python , pony orm and postgres has significantly improved..... again, many thanks! This will make the security of our TG groups much improved!!
Karsten
Hello, I am using Pony in a Qt5 application and doing queries in a thread (QThread). with Python 3.9 everything works fine! under Python 3.10 the application is terminated with the following code:
Process finished with exit code -1073741819 (0xC0000005)
If I comment out the pony function everything is fine.
I'm using Pony 0.7.15rc1. Here the query:
Karsten
@db_session(immediate=True)
def get_all_in_time_delta(self, t_from: datetime, t_to: datetime, net: str, item_group_selection: ViewMode):
try:
if item_group_selection == ViewMode.ALL:
return (select(r for r in BlzEvent if r.event_time >= t_from and
r.event_time <= t_to and
r.net == net).order_by(BlzEvent.event_time)).fetch()
elif item_group_selection == ViewMode.ACTIVATED:
return (select(r for r in BlzEvent if r.event_time >= t_from and
r.event_time <= t_to and
r.net == net and
r.action == '').order_by(BlzEvent.event_time)).fetch()
elif item_group_selection == ViewMode.DEACTIVATED:
return (select(r for r in BlzEvent if r.event_time >= t_from and
r.event_time <= t_to and
r.net == net and
r.action != '').order_by(BlzEvent.event_time)).fetch()
except Exception as ex:
return ''
Alexander
Thank you for the report! That's interesting...
Alexander
It looks like access violation. Pony is pure-Python and probably cannot produce this type of error. Qt looks more suspicious in this regard
Alexander
Maybe the problem is not with the query itself, but with Qt state when it processes the query results
Karsten
The version of QT has not changed. The python version is now 3.10 and the pony version is 0.7.15rc1 as said before. It worked on Python 3.9. All pony functions are in one class. The instance is completely handed over to the thread.
Alexander
Do you mean PyQt or just pure Qt?
Ben
Hi! Is there any Attribute Option to set a column definition (for compatible databases that support metadata)
Alexander
Hi! What do you mean? Can you provide an example?
Karsten
Do you mean PyQt or just pure Qt?
I mean PyQT. I suspect a connection with the new Python version. However, my knowledge is not that deep. I can't get any results with breakpoints.
Alexander
As far as I remember you can wrap your code with try-except and it will most likely show you the real error.
Alexander
But I'm a big expert as well, just remember some workarounds
Karsten
I'm just trying something...
Karsten
I used try-except in all critical places, but the application exits without warning!😡
Volbil
Alexander
This error looks like an invalid pointer exception produced by some binary code (Qt in my guess)
It cannot be caught by a traceback
Alexander
Maybe you can add print("debug string", flush=True) before and after query to be sure that the error is not caused by the query execution
Volbil
Volbil
From my experience Qt is one big mess
Karsten
won't be caught either! only output in the console: Process finished with exit code -1073741819 (0xC0000005)
Alexander
Then I suspect the error in some different place, and the query execution just triggered a problematic code path execution