Alexander
Probably it was Alexey Malashkevich @cryptoalexey, PonyORM co-creator
Sigmund
Ahh, now you mention it the name sounds familiar
Anonymous
@metaprogrammer, about those PKs: thank you for such a thorough and detailed answer. I really appreciate it.
Anonymous
If the __getitem__ is fixed now, I'll use the flat keys instead of nested. Maybe it's just a matter of getting used to it. :-)
Alexander
Yes, it is fixed now in this commit: https://github.com/ponyorm/pony/commit/1934624b7aa5f4106a62aa0b6bf90c94a8c395a7 I think primary key structure can be treated as a "black box", so most probably it should not cause any problem in your application, but, as I said, it is possible to implement support of nested PKs in a pair of separate functions. It just problematic to add it to the current getitem method
Matthew
A and B both have categories = Set(Category), how would I write a query efficiently to find A where it shares at least one category with a given B ?
Alexander
A.select(lambda a: b in a.categories.related_b_set)
Roberto
I have a question: is it possibile to use something like @db_session decorator for a async function? I mean, if I write my own decorator that simply puts with db_session around the function await, will it work?
Alexander
@db_session decorator can be applied to async function, it should work as expected.
Alexander
But db_session context manager cannot wrap async code
Alexander
Because in Python a context manager cannot track when async function suspends
Roberto
@db_session decorator can be applied to async function, it should work as expected.
I get an error applying @db_session to an async function, it says "function not awaited"...
Alexander
Can you show the traceback?
Roberto
Can you show the traceback?
No traceback, only this error: RuntimeWarning: coroutine 'ScontinoAnswerer.on_chat_message' was never awaited await self._router.route(msg) (i'm using telepot for a telegram bot)
Alexander
I think the error is not related to db_session, you probably just invoke async function incorrectly. See https://xinhuang.github.io/posts/2017-07-31-common-mistakes-using-python3-asyncio.html I think that Python async concepts is a bit complex to understand, and may be error prone
Alexander
It would be great if you can make reproducible example
Adam
for async i use "with db_session:" in the function, not the @ and it works just fine
Roberto
for async i use "with db_session:" in the function, not the @ and it works just fine
I'm using that at the moment but I'd prefer the decorator in order to avoid an extra indentation level...
Lucky
Is there a method to have a entity to reload data from the database? Like obj.reload(discard_changes=True)?
Alexander
obj.load() should work for this
Lucky
I need to reload it in unit test after I called an API command. Therefore I can't set attributes volatile.
Matthew
use two db sessions
Lucky
Hmm, how can I do that? Flask's app.test_client() calls the API internal code directly, so the @orm.db_session in the API is already started.
Alexander
obj.load() doesn't help?
Valentin
@cicca Maybe I'm too late but you can create your own decorator with "with db_session:" in it to avoid extra indentation level. I did it once but I don't have access to that code now. On the other hand, it is not so difficult. It should be something like: def async_db_session(fn): async def callback(*args, **kwargs): with db_session(): return await fn(*args, **kwargs) return callback I didn't test it now but even if it doesn't work, you got the idea.
Valentin
Well, atleast it worked some time ago. :)
Carel
@metaprogrammer I meant to ask if you’d seen the Android room ORM ? In particular I was curios if you were aware of their migration implementation, I know you are implementing that and I thought it might have some use as a blue print of sorts. I suspect some one would’ve mentioned this before but just in case no one did. Granted it’s Javascript/Kotlin etc. but it might be worth a squeak.
Alexander
Hi Carel! No, I'm not aware about Android room ORM, you can share link with description of how its migrations work
Carel
I’m still learning to use it but it seems you annotate the database with a version string whenever you first creat the tables/entities, then change the annotation as you add/modify the tables/entities. The android build system then generates a “database state” file for each annotation when you compile the application. It seems the migrations are inferred from these state files but there is still some manual work involved in using them. If I find out more I’ll report back but I don’t understand java/Kotlin enough yet to dig through the sources just yet, still learning android at the moment. The room API just feels a heck of a lot like the pony and I noticed they semi automated the migrations. These annotated state files are simply json files by the look of it.
Carel
I can’t find any links on how it works :( the docs on how to use it are about 10-20 pages and consist of the tutorial https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/ and the api reference https://developer.android.com/topic/libraries/architecture/room. I haven’t found much more on it. The articles on medium simply regurgitate of these docs.
Carel
Kotlin seems to be an attempt at making java like python. If you need more info I’ll try supply it as I work with this stuff.
Alexander
Ok, thanks, I'll take a look
Carel
Oh yeah, there are two videos the lengthy google IO one https://m.youtube.com/watch?v=MfHsPGQ6bgE and the quickie https://m.youtube.com/watch?v=SKWh4ckvFPM
Carel
Sure thing, hope it’s more help then it is a waste of time :)
Alexander
Guys. We just pushed Array support on GitHub. Please take a look if you can https://docs.ponyorm.com/array.html
Alexander
It should work in PostgreSQL and also there is basic support in SQLite
Alexander
The benefit of arrays vs JSON is that it PostgreSQL arrays support operations item in array and subset in array which can use GIN index
stsouko
WOW! Great!
stsouko
я ждва года ждал!
Alexander
:)
Alexander
stsouko, also I fixed prefetch problems that you've described. Now prefetch should work much more efficiently, with the minimal amount of additional queries
stsouko
that's cool. Now I can simplify the code and remove work-arounds)) Thank you very much!
Alexander
query.to_pandas() is almost ready, but probably can't finish it until Saturday
stsouko
Nice. I will test arrays today-tomorrow. I will wait for the release of pandas support. for my chemical cartridge this is very useful feature)
Alexander
Yes, it would be great if you can test arrays before official release
Alexander
They work fine in our tests, but we could miss some use-cases
stsouko
class Product(db.Entity): id = PrimaryKey(int, auto=True) stars = Optional(IntArray) db.bind('sqlite', ':memory:') db.generate_mapping(create_tables=True) p=Product() p.stars.extend([1,2,3]) Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'extend'
stsouko
for optional arrays may be will be more conveniently autocreate empty array if need?
stsouko
currently workaround if p.stars and p.stars.extend(arr) or p.stars = arr
stsouko
but if for integers or strings behavior is same, this not a reason for change api
Alexander
Guys, what do you think, do we need to treat Optional arrays as nullable, or are they should be declared as NOT NULL, but empty by default, while Required arrays should be non-empty? In other words, should we apply the same logic as for strings, where Optional(str) is NOT NULL by default, but uses empty string as a default value? I think it makes sense
Alexander
So, Optional(IntArray) will be NOT NULL, and have empty array as a default value, while Optional(IntArray, nullable=True) will defaults to None
Alexander
I think it will be consistent with the current design, so I'm for this
Alexander
ok
Vitaliy
IMHO it will be better. Because the user can control this behavior using nullable argument, otherwise this argument for such type is unusabe
Alexander
That's a good point
Matthew
https://m.signalvnoise.com/update-on-basecamp-3-being-stuck-in-read-only-as-of-nov-8-9-22am-cst-c41df1a58352
Matthew
I post this because they used normal integers for a primary key, so new rows couldn’t be created. They say that rails switched to using bigint two years ago. This has hit me before with pony, maybe pony should switch to bigint by default?
Matthew
Hi,
Matthew
models.select((p, p.reviews.variation_asin) for p in models.ReviewProduct)[:]
Matthew
This query works
Matthew
models.select((p, p.reviews.variation_asin, models.min(p.reviews.review_date), models.max(p.reviews.review_date)) for p in models.ReviewProduct)[:]
Matthew
This blows up with error: ProgrammingError: table name "review" specified more than once
Matthew
This is the pony-generated SQL:
Matthew
SELECT "p"."id", "review"."variation_asin", MIN("review"."review_date"), MAX("review"."review_date") FROM "reviewproduct" "p" LEFT JOIN "review" "review" ON "p"."id" = "review"."product" LEFT JOIN "review" "review" ON "p"."id" = "review"."product" GROUP BY "p"."id", "review"."variation_asin"
Matthew
Am I using pony wrong or is this a bug?
Matthew
Postgres is the database
Matthew
Thee query works if I remove the redundant left join
Matthew
I have tried reordering the query but same result
Matthew
@metaprogrammer I think it's a bug, maybe pony doesn't expect a second left join to happen?
Alexander
Hi Matthew! Yes, it looks like a bug. I'll try to fix it in the evening
Matthew
Thank you :)
Anonymous
Hello! Is there any easy way to use SELECT … FOR UPDATE SKIP LOCKED in Pony?
Anonymous
I would like to get the first row in the results, but for now I'm only aware of NOWAIT, like this: select(a for a in A).for_update(nowait=True).order_by(A.name).limit(1).
Anonymous
This will unfortunately cause an error even if there is more than one row.