Karsten
class ViewFilterThreadClass(QThread): thread_finished = pyqtSignal(bool) def __init__(self, parent=None): QThread.__init__(self, parent=parent) self._dal: DataAccessLayerClass = DataAccessLayerClass() self._tw: QTableWidget = QTableWidget() self._net: str = "" self._view_from: datetime = datetime.now().date() self._view_to: datetime = datetime.now().date() self._view_mode: ViewMode = ViewMode.ACTIVATED self._reporter: str = '' self._reporter_func: str = '' self._line: str = '' self._train: int = 0 self._location: str = '' self._code: str = '' self._category: str = '' self._delay: int = 0 def set_properties(self, dal: DataAccessLayerClass, tw: QTableWidget, net: str, view_from: datetime, view_to: datetime, view_mode: ViewMode, reporter='', reporter_func='', line='', train=0, location='', code='', category='', delay=0, parent=None): self._dal = dal self._tw = tw self._net = net self._view_from = view_from self._view_to = view_to self._view_mode = view_mode self._reporter = reporter self._reporter_func = reporter_func self._line = line self._train = train self._location = location self._code = code self._category = category self._delay = delay def run(self): try: result = self._dal.get_filter_in_time_delta(self._view_from, self._view_to, self._net, self._view_mode, self._reporter, self._reporter_func, self._line, self._train, self._location, self._code, self._category, self._delay) except Exception as ex: print(ex.args) pass self._tw.setRowCount(0) query_result_to_table_widget(self._tw, result) self.thread_finished.emit(True)
Karsten
In the last line the application crashes! No braik point and no try-except will help
Karsten
I think my knowledge is not good enough for that.
Karsten
What I don't understand, with Python 3.9 the code works!
Alexander
I think you need the event loop started in the main thread to process signal emitting
Alexander
like app = QApplication() app.exec_() or something like that
Karsten
def _on_btn_view_all_clicked(self): """ with thread """ if self.frame_csv.isVisible(): return self.can_refresh = True # view progress window dt_view_from: datetime = self.dt_view_from.dateTime().toPyDateTime() dt_view_to: datetime = self.dt_view_to.dateTime().toPyDateTime() self.prg_wnd.show() if (dt_view_to - dt_view_from).days > 0: # self.setEnabled(False) self.prg_wnd.show() self._thread_running = True # initial and run thread self.view_all_thread.set_properties(self.dal, self.table_widget, self.net, dt_view_from, dt_view_to, ViewMode(self.table_view_index)) self.view_all_thread.start() while self._thread_running: qApp.processEvents() # self.prg_wnd.close() self.table_widget.resizeRowsToContents() # notwendig ! wird im thread (query_result_to_table_widget) nicht ausgeführt
Karsten
In the main thread I'm waiting for the end of the rendering in the TableWidget : self._tw.setRowCount(0) query_result_to_table_widget(self._tw, result) Then I close the widget self.prg_wnd (Progress)
Vitaliy
Hi @metaprogrammer ! It seems I found a bug in 0.7.15rc1. Query example that FAILS: select(s for s in Session if s.lastseen > datetime.utcnow() - timedelta(days=30)).first() Query example that PASS: select(s for s in Session if s.lastseen > datetime.utcnow() - timedelta(30)).first() I've digged into file pony/orm/asttranslation.py, line 210, function `postCall(translator, node)`: There args and kwargs of some function used inside query combined in the single list: `args = [ arg.src for arg in node.args ] + [ kw.src for kw in node.keywords ]` Further follows a check: if len(args) == 1 and isinstance(node.args[0], ast.GeneratorExp): return node.func.src + args[0] It will cause IndexError: list index out of range if we use ONLY kwargs inside function. If we change isinstance(node.args[0], ast.GeneratorExp) to isinstance(args[0], ast.GeneratorExp) then the error is not thrown.
Alexander
Cool, thank you!
Volbil
Hello everyone, I had this question for a long time. What is the most optimal data type for financial transactions in Pony and/or what approach would be recommend? Obviously float is out of the question due to rounding error. I've used Decimal for that purpose but its not very convenient to use (due to conversions and etc) and it has some unexpected bugs time to time. Another solution I had in mind for a while is using int with size=64 (max value 9223372036854775807) and it would be ok for storing values with 2 decimal places but it won't be enough for values with more decimal places (for example Bitcoin amounts has 8 decimal places and Ethereum 18 and etc). How you approach this issue in your projects while using Pony?
Volbil
Any feedback would be appreciated :)
Ben
Hi! What do you mean? Can you provide an example?
For example I have a table "Client" with a field "name". I could have: class Client(db.Entity): _description_ = 'This table contains end-clients' name = Required(str, description='The first name of the client') And pony would do something like "COMMENT ON TABLE client IS 'This table contains end-clients';"
Volbil
Maybe it's just sqlite issue, but still
Volbil
Also working with Decimal library feels bit janky
Alexey
@alexey115 this bug happens to me time to time
How do you get the balance value? Do you convert it from a float value at any point?
Alexey
Also working with Decimal library feels bit janky
It is, but no other Postgres type supports uint256. I believe that for full compatibility the PG type should be declared as numeric(78). Like it is discussed here https://stackoverflow.com/questions/50072618/how-to-create-an-uint256-in-postgresql
Volbil
How do you get the balance value? Do you convert it from a float value at any point?
It was floating point issue with SQLite, so there is no way around it (for SQLite)
Volbil
Thats why I asked, in case somebody found better way to do that
Alexander
If you're not doing anything with it on db side you can store it as string.
Valentin
Hi everyone. I've got a problem. Pony generates this sql: [2022-01-23 02:52:55,532] INFO: UPDATE `dbtrait` SET `data` = %s WHERE `dn` = %s AND `game_object` = %s AND (`data` = CAST(%s AS JSON)) [pony.orm.sql] [None] And throws: ... File "/home/xunto/.local/share/virtualenvs/tales_system_service-2lRreFFq/lib/python3.9/site-packages/pony/orm/dbapiprovider.py", line 64, in wrap_dbapi_exceptions raise ProgrammingError(e) pony.orm.dbapiprovider.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'JSON))' at line 5") I'm using mariadb:10.7. It happens when I update this Model using upsert method: https://gist.github.com/xunto/c1871c9c6cbf28b2805ebda79b27d14f
Valentin
Any idea what to do?
Alexander
Hello. It seems that this syntax is supported in MySQL (https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_cast) but not supported in MariaDB (https://mariadb.com/kb/en/cast/#comment_3157)
Valentin
Ah, interesting. Any workarounds for that? Also, sorry for late messaging, I hope I didn't wake you up. I expected to get answer in the morning.
Alexander
I'm thinking about it. No worries, telegram isn't that aggressive in terms of notifications
Alexander
Can you show the query itself?
Valentin
You mean the upsert call?
Alexander
Ah sorry, didn't notice that huge gist link
Alexander
Why don't you try something like trait = DBTrait[db, owner] or DBTrait() trait.data = data ?
Valentin
Still happens.
Valentin
But isn't DBTrait[...] throwing ObjectNotFound if not found? So this should work for situation where record is missing?
Alexander
Ah, I meant DBTrait.get(...)
Valentin
Still happens with: @classmethod def upsert(cls, db_game_object: DBGameObject, dn: str, data: Dict) -> DBTrait: trait = DBTrait.get(dn=dn, game_object=db_game_object) or DBTrait() trait.data = data return trait
Alexander
If any json updates don't work for MariaDB, I think the only way is to create some function with raw sql generation.
Alexander
Or you can wait for another Alexander to reply. He sometimes creates some magical workarounds)
Valentin
Hah, okay. Thanks, It would be great if he found a way. I'll stick to raw sql for now.
Владимир
Any chances to get new release?
Volbil
Any chances to get new release?
As far as I know recently there was release for Python 3.10
Alexander
I'm preparing a stable release, should be released tomorrow
Rozen
:O
Alexander
https://pypi.org/project/pony/0.7.15/ 🤫
Alexander
https://github.com/ponyorm/pony/releases/tag/v0.7.15
Volbil
:D
Владимир
Fantastic!
Alexander
Now PonyORM supports Python 3.10. Also, now you can create SQLite memory database which is accessible from multiple threads by specifying :sharedmemory: "filename". (The previous way of creating in-memory database with a :memory: filename does not allow using the database from different threads)
Christian
Nice! Well done on overcoming that milestone! 💪
Radim
thanks for a wheel!
Alexander
Sure!
Alexander
Quick bugfix release, which fixes PostgreSQL-related issue: https://github.com/ponyorm/pony/releases/tag/v0.7.16
Ronke Akanni
hi
Alexander
Welcome if you are not a bot :)
Vitaliy
Hello dear developers! I have found new bug related to isinstance function. For simplification consider reduced entities: class Session(db.Entity): id = PrimaryKey(int) user = Required('User') class User(db.Entity): id = PrimaryKey(int) type = Discriminator(str) sessions = Set(Session) class Worker(User): pass class Admin(Worker): pass Build a query to get staff online now: five_min_ago = datetime.utcnow() - timedelta(minutes=5) select(s for s in Session if s.lastseen >= five_min_ago if isinstance(s.user, Worker) It produces following SQL (at least for MySQL): SELECT `s`.`id`, ...bla bla..., `s`.`user` FROM `session` `s` WHERE `s`.`lastseen` >= %s AND `s`.`type` IN ('Admin', 'Worker') But it should be something like this: SELECT `s`.`id`, `s`.`user` FROM `session` `s`, `user` `u` WHERE `s`.`lastseen` >= 0 AND `u`.`type` IN ('Admin', 'Worker') AND `u`.`id` = `s`.`user` To workaround I can add for u in User if u == s.user to the query and change isinstance to check u instead of s.user. Another way is to know what exactly types of users and its heirarchy I have and check as strings if s.user.type in ('Worker', 'Admin'). But both ways are inconvenient.
Alexander
Looks like a bug, thank you for reporting it!
Oleksandr
When i add record - how i can get record ID?
Oleksandr
Just search only?
Alexander
obj = MyEntity(foo=1, bar=2) flush() print(obj.id)
David
Hi all, How Can I get the value with highest occurrences for a specific column? Tried: SELECT some_str, COUNT(some_str) AS some_str_occurrences FROM some_table GROUP BY some_str ORDER BY some_str_occurrences DESC LIMIT 1; But if more than one value appear same no of times (which is max) I want to return empty result.
Alexander
You can do something like from pony.orm import count, desc q1 = select( (obj.some_str, count()) for obj in MyEntity ).order_by(-2) # order by second column, descending results = q1[:2] # limit to 2 rows if not results: print("empty table") return elif len(results) == 1: row1 = results[0] else: row1, row2 = results if row1[1] == row2[1]: print("no highest value") return print("highest value is", row1[0])
Alexander
CREATE VIEW some_str_count AS SELECT some_str, COUNT(*) as cnt FROM some_table GROUP BY some_str SELECT some_str FROM some_str_count t1 WHERE NOT EXISTS( SELECT * FROM some_str_count t2 WHERE t2.some_str != t1.some_str AND t2.cnt >= t1.cnt )
Alexander
migrations ... ? 🥺
Now, after implementing Python 3.10 support, we can focus on migrations :)
Elraro
Hi! I'm getting the following error: pony.orm.core.UnexpectedError: Object Item[new:1] cannot be stored in the database. OperationalError: 1364 Field 'publish_date' doesn't have a default value 2022-01-31T10:07:02.257980132Z But, i understand that publish_date is getting the default value at database level: class Item(db.Entity): id = PrimaryKey(int, auto=True) item_id = Required(str) chat_id = Required(str) title = Required(str) price = Required(float) url = Required(str) user = Required(str) publish_date = Required(datetime.datetime, sql_default="CURRENT_TIMESTAMP") observaciones = Required(str) item = Required(str) What is wrong?
Alexander
Hi! What database do you use?
Elraro
Hi! What database do you use?
Im using Mariadb. Also, the Item query: new_item = Item(item_id=item_id, chat_id=chat_id, title=title, price=price, url=url, user=user, observaciones="prueba", item="prueba")
Alexander
It is possible that you added the sql_default option after you had already create the tables, in that case it will not affect existing tables. You can apply change manually by executing the following command in db admin interface: alter table item alter column publish_date set default current_timestamp
Elraro
no, because i dropped all the database before hehe, but give me a minute, i will drop all again
Владимир
Good evening! I was testing the ORM's features when stumbled upon a problem. Here's my code. I'm trying to create a one-to-one connection, and for some reason this code just won't create the 'profile' column for the 'User' table. Do you have any suggestions on how I can fix this?
Владимир
Alexander
In one-to-one relationship, the column is created on a side with Required attribute. It is not necessary to create columns on both sides, one column is enough