Henri
(Polish Carpathian mountains near Ukraine)
Alexander
I was joking, but maybe Henri is serious :)
Henri
Yep I am! 😊
Henri
But no need to feed him.
ichux
But no need to feed him.
I guess it feeds around the mountain
Henri
Do you use it as a personal account or an organization one?
Personal account but upgraded to business account (free).
Henri
I guess it feeds around the mountain
Actually soon should go to take his winter sleep as we already have deep snow all around.
ichux
Actually soon should go to take his winter sleep as we already have deep snow all around.
Please send me pictures of it, privately, if you're able to.
Henri
Please send me pictures of it, privately, if you're able to.
I mostly see only his foot steps :) But a friend of mine is wild animal photographer. So maybe I can ask him.
ichux
Dear admin, I could donate up-to $1000, but I doubt if there's a means for me to do such now. I plan relocating to a Western country next year, all other things being equal. I should be able to do such easily then. Thanks
Lucky
Ok, i should program an orm too xD
Anonymous
Hi - I might be having a brain meltdown, but I am convinced that this should work: with orm.db_session: g1 = orm.select(ol for ol in db.Orderline if ol.qty >= 3) orm.show(g1) # works g3 = orm.select(ol for ol in db.Orderline if ol.qty <= 5) orm.show(g3) # works. g4 = orm.select(ol for ol in g1 if ol.qty <= 5) orm.show(g4) # typeError? But pony throws the exception in g4: TypeError: Cannot iterate over non-entity object
Anonymous
I can achieve the goal (in g4) using g1.filter(lambda ol: ol.qty >= 5), but that's not so pretty I guess...?
Anonymous
My thinking is that it seems less pythonic to having to use filter and lambdas, rather than passing the previous query object in (g1).
Matthew
I don't think it's possible unless you do g4 = orm.select(ol for ol in db.Orderline if ol.qty <= 5 and ol in g1)
Alexander
I agree that we need to support select(x for x in <query>) too, it will be more intuitive to build query step-by-step this way. We just have no time to implement it yet. In the future we will add it for sure
Anonymous
Right now I'm laughing my buts off. This actually works too: def gen(query): for i in query[:]: yield i g5 = list(ol for ol in gen(g1) if ol.qty <= 5) orm.show(g5)
Anonymous
Any comments?
Alexander
It works in Python, not in SQL. So all rows from g1 are loaded into memory
Anonymous
Yes - I take the hit in memory, but the syntax is easier for to read. I'll look at the ponyorm source code and return ..
Matthew
The performance would probably be pathological with a lot of query results
Matthew
filter is fine imo
ichux
@fabirovsky Good day. I noticed that you viewed my LinkedIn profile.
Yurii
Yes, I did it.
ichux
Yurii
You sent a link and I decide to open it. No more.
ichux
Ghulam
Hi guys, I encountered an exception when tried to use .to_json method saying user nobody has no permission to view ..etc. I search for google and found ponyjs slipped in the ponyorm ref doc but no actual links to it. I could read some question at stackexchange answered by @akozlovsky (i recall) that pony has some user management hidden in it, but couldn't find complete doc about it. I currently doing some APi development but still looking for user management/policy on it, if pony has built in support for it it would be great, any thought?
Ghulam
I'm using falcon as API engine, would it fit altogether, I haven't take a look Morepath before..
Henri
No experience with falcon I'm actually helping with development of Morepath and I also wrote the ponyorm integration. It fits really perfectly.
Ghulam
Ok, I'll take a look then, thanks..
Henri
Here is an example (still beta) : https://github.com/yacoma/morepath-realworld-example-app
Pablo
/whoami@bonbot
Alexander
I still don't get the meaning of the bot
Juan Antonio
+1
Matthew
https://gist.github.com/anonymous/a073810f82f4c5d36ff74e955977f209
Matthew
The error is:
Matthew
pony.orm.core.ERDiagramError: Reverse attribute for ListingAlertsListing.alerts not found
Matthew
Do I need two Alert Sets?
Matthew
Ideally I'd only have one Alerts set
Alexander
Your reverses is not correct btw.
Alexander
It cannot be done the way you want. Alexander (not me) will explain why soon.
Alexander
In Pony each relationship is defined by two attributes. So you need to add previous_alerts Set attribute to ListingAlertListing class. Also, if I understand the meaning of the schema correctly, reverse option values for current_listing and previous_listing attributes of Alert class should be alerts and previous_alerts
Alexander
Maybe I'm not fully understand what you want to achieve with that schema
Alexander
In most cases you can just ignore previous_alerts attribute, but sometimes it may be useful too
Matthew
Thank you, I used two sets and it worked, having one set didn't matter in the end
Anonymous
Hi Guys, I'm selecting a slice with orm.select(o for o in db.Order)[start:end] and can do: [:] with the end part being empty. [10:20] also works, but [10:] fails. Is this a bug or a feature?
Anonymous
[10:-1] also seems non-compliant: with orm.db_session: g = orm.select(o for o in db.Order)[10:-1] print([i.id for i in g]) >>> []
Alexander
Slice is translated to LIMIT section of SQL query. The section purpose is to limit the number of rows returned from the database and not load all millions of rows into memory. Such query can be executed much faster. On the other hand, the slice [10:] means "throw out just first 10 rows and the load all millions of the remaining rows into a memory", it is not supported in SQL and cannot improve the query performance. If you really want to load all rows and then trow out the first 10 you can do it in memory after the query is executed: orm.select(o for o in db.Order)[:][10:]
Anonymous
I need to chain a stack of generators together to retrieve N rows.
Anonymous
However I don't know how many rows I need to pull from the data source to populate the page that the user is looking at. All I know is that user has clicked onto page N and that each page contained, say for example 50 rows.
Anonymous
With a chain of generators, the operation is similar to: records = [] while len(records) < 50: records.append(next((f(e(d(c(b(a(some_table)))))
Anonymous
Note that the chain of generators (f,e,d,c,b,a) is created dynamically.
Anonymous
it almost as I'm trying to use the query as generator: q = orm.select(o for o in db.Order) # query object next_row = next(q)
Anonymous
However if I load all rows and discard them, I loose the predictability of the memory footprint that the generator would give me.
Alexander
Try to use page method of the query. It is equivalent to slice, but its API looks nicer: q = orm.select(o for o in Order) objects = q.page(10, pagesize=50)
Alexander
I doubt you can make en efficient code with chain of generators in this case
Anonymous
I think it isn't that horrible: sqlite already uses fetchmany https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.fetchmany psycopg uses itersize http://initd.org/psycopg/docs/cursor.html#cursor.itersize so the performance hit has already been taken. The missing element is that the orm doesn't implement the iterator method next on the query object which exploits the features of the db-providers.
Anonymous
For now I will implement a manual slice manager that then repeatedly executes orm.select( .....)[offset: offset+pagesize] and increments the offset. 😊
Alexander
There are several things here: 1) It is significantly more efficient to skip initial rows directly in the database and not in the application memory, because in that case database can retrieve just primary keys of initial rows and not allocate all row content in memory. When someone do iteration on query result just to trow initial rows out, all layers of ORM, database connection driver and database engine need to perform unnecessary work of allocating row data in various buffers. So, good paginated query contains LIMIT...OFFSET... clause. It is even better to have condition AND id > max_prev_id in WHERE section of query instead of OFFSET, but it is not always possible. 2) Using iteration on cursor is a bit slower then fetching all rows in a single action, but may be better if we iterate over millions of rows and previous rows can be garbage collected before we retrieve all rows from the query. If ORM uses identity map pattern, the previous rows cannot be garbage collected, because they all remain cached inside the identity map. So, an ORM with identity map does not have benefit from using iteration API of database cursor object
Anonymous
Hep - back again 😊 Could we perhaps add the following to the documentation under mapping customization (https://docs.ponyorm.com/entities.html#mapping-customization), please: ... To list the declared entities in a database model, db.entities lists all tables and their entityMeta objects as a dictionary. To view the individual tables' column names programmatically use table._adict_ example: >>> for table,cols in m.entities.items(): ... print(table, cols) ... for colname, table_col_name in cols._adict_.items(): ... print(colname, table_col_name) ... PackSize <class 'dce_dbmodels.model.get_new_model.<locals>.PackSize'> # key:table, value: columns id PackSize.id # key: column name, value: "table.column_name. products PackSize.products size PackSize.size pack_type PackSize.pack_type UoM_length PackSize.UoM_length length PackSize.length width PackSize.width height PackSize.height UoM_volume PackSize.UoM_volume volume PackSize.volume UoM_weight PackSize.UoM_weight weight PackSize.weight LuM <class 'dce_dbmodels.model.get_new_model.<locals>.LuM'> name LuM.name pack_sizes LuM.pack_sizes ...
Anonymous
(unless of course if I'm abusing the api?)
Alexey
Alexander
I think we can add db.entities and entity._adict_ to documentation. But the suggested text needs to be rephrased. db.entities is a dict and not a list, it maps entity name to entity class. entity._adict_ maps attribute name to attribute descriptor object. It has nothing to do with table or column names. It is often more convenient to use entity._attrs_ list instead of entity._adict_ mapping. entity._attrs_ is a list of all attribute descriptors listed in a declaration order. In order to get table name someone can access entity._table_ property, its value can be a string or a tuple if table name includes schema name as well. The column name can be retrieved from attribute descriptor using attr.column property. Some attributes map to multiple columns, so it is better to use attr.columns property, which returns list of all columns for given attribute. With this changes, the example code will look as: for entity_name, entity_class in db.entities.items(): print(entity_name, entity_class._table_) for attr in entity_class._attrs_: print(attr.name, attr.columns)
Anonymous
Hep - back again 😊 Could we perhaps add the following to the documentation under mapping customization (https://docs.ponyorm.com/entities.html#mapping-customization), please: ... To list the declared entities in a database model, db.entities lists all tables and their entityMeta objects as a dictionary. To view the individual tables' column names programmatically use table._adict_ example: >>> for table,cols in m.entities.items(): ... print(table, cols) ... for colname, table_col_name in cols._adict_.items(): ... print(colname, table_col_name) ... PackSize <class 'dce_dbmodels.model.get_new_model.<locals>.PackSize'> # key:table, value: columns id PackSize.id # key: column name, value: "table.column_name. products PackSize.products size PackSize.size pack_type PackSize.pack_type UoM_length PackSize.UoM_length length PackSize.length width PackSize.width height PackSize.height UoM_volume PackSize.UoM_volume volume PackSize.volume UoM_weight PackSize.UoM_weight weight PackSize.weight LuM <class 'dce_dbmodels.model.get_new_model.<locals>.LuM'> name LuM.name pack_sizes LuM.pack_sizes ...
The revised example code gives me: >>> for entity_name, entity_class in m.entities.items(): ... print(entity_name, entity_class._table_) ... for attr in entity_class._attrs_: ... print(attr.name, attr.columns) ... PackSize None id [] products [] size [] pack_type [] UoM_length [] length [] width [] height [] UoM_volume [] volume [] UoM_weight [] weight [] LuM None name [] pack_sizes [] VuM None Where I think the dot notation is actual helpful as it tells us what table it belongs to.
Alexander
I think it is because you do it before calling generate_mapping
Anonymous
Qoute: [flat is better than nested]
Anonymous
(Y)
Anonymous
Yes