Lucky
Your requested sticker.
Lucky
See the sticker pack URL
Lucky
This just blow my database.
Mikki
Welcome!
Andrew
Thanks!
Lucky
(How) can I order elements in a Set? pack = StickerPack.get(url=shortname) sticker_list = pack.stickers Now pack.stickers.order_by(Sticker.file_id)? Probably like this? stickers_list = orm.select(s for s in Sticker if s.sticker_pack and s.sticker_pack.url == shortname).order_by(Sticker.file_id)
Lucky
Is that the way to do it?
Alexey
Did it work for you?
Alexey
You can have even more complex ordering condition using lambdas https://docs.ponyorm.com/api_reference.html#Set.order_by
Lucky
Yes, It works.
Mikki
Welcome!
Artem
@Mikkass Thanks.
Lucky
Can I apply queries when getting elements from a Set attribute?
Lucky
Summary: isinstance(pack, StickerPack) and orm.select(s for s in pack.stickers) results in TypeError: Cannot iterate over non-entity object
Lucky
pack.stickers is of type orm.Set
Lucky
Apperantly not
I think I can do that on python side, with: data["stickers"] = [_sticker_to_json(s, add_pack_info=False) for s in [s_ for s_ in pack.stickers if not "nsfw" in [t.string.lower() for t in s_.tags]][:include_stickers]]
Lucky
But that kinda sucks.
Lucky
What is the best way to do it? Doing it in-memory on python side is not what I really want to do...
Lucky
In any case, here my relevant data stucture, but it didn't change much. class Sticker(db.Entity): file_id = Required(str) # BQADBAAD6QIAAqQW9AX8GaFqUwWnrgI emoji = Required(unicode) # ❓ sticker_pack = Optional('StickerPack', column='sticker_pack_url') tags = Set('Tag', cascade_delete=True) sticker_messages = Set('StickerMessage') tl_id = Optional(int, size=8) # The id field of the telegram api schema the apps use. tl_access_hash = Optional(int, size=8) # The access_hash field of the telegram api schema the apps use. PrimaryKey(file_id, emoji) class Tag(db.Entity): id = PrimaryKey(int, auto=True) user = Required(User, column='user_id') message_id = Optional(int) # Of the message with the text, the tag. None means it got added via web gui. sticker = Required(Sticker) string = Required(unicode) use_global = Required(bool, default=False) composite_key(user, sticker, string) class StickerPack(db.Entity): url = PrimaryKey(str) title = Required(str) owner = Required(User, column='owner_id') stickers = Set(Sticker) first_seen = Required(datetime, sql_default='NOW()')
Alexander
At this moment there is a technical limitation, that only entity class can be used as a source of generator. We can overcome it, but other tasks were more important. If you want to select from a collection you need to use lambda syntax: result = pack.stickers.select( lambda s: ...)
Lucky
I'll try that, and hope this will be added eventually. But indeed this is not the most urgent feature to have :D
Lucky
Lucky
Not quite sure how to write that query tho
Alexander
lambda should return true for objects you want to select. like: student1.courses.select(lambda c: c.credits > 20 and "philosophy" in c.name.lower())
Lucky
Oh. I see.
Lucky
I removed the if ... else ..., so It will return a boolean.
Lucky
But it seems lambda s: "nsfw" not in [t.string.lower() for t in s.tags] is not possible? Still failing with TypeError: LIST_APPEND() takes 1 positional argument but 2 were given
Alexander
Try to use generator instead of list comprehension: (...) instead of [...]
Lucky
Wow, it works
Lucky
This concept of using (...) instead of [...] always confuses me
Alexander
Apparently, we need to fix bytecode decompiling for [...] in last Python. They both should work. The fix should be pretty easy
Lucky
I am using ... hold on
Lucky
python3.5
Lucky
To be exact: Docker, tiangolo/uwsgi-nginx-flask:flask-python3.5
Anonymous
Hi, I'm using pony and I want to return list of results from a function with the @db_session decorator. the results are the relations from one of my classes. however when I try to access the properties of those results outside the function I get pony.orm.core.DatabaseSessionIsOver: Cannot load attribute Ramal[2].ramal: the database session is over . How can I query all properties from those objects and return them to use them later?
Alexey
Hi Federico Why don't you process the objects inside the db_session?
Anonymous
I was trying to modularize and save the results obtained in the search to be used in other functions.
Alexey
what if you could convert the result to JSON?
Anonymous
How would I do that?
Alexey
this is something we are working on now
Anonymous
glad to hear that, would it be a good idea to also add a way to copy the result to a python dictionary to be used outside the db_session?
Anonymous
thanks for the help, I'm really liking the orm!
Alexander
Currently you can use to_dict method of entity instance. You can get a query result and convert it to list of dicts using a list comprehension.
Alexey
https://docs.ponyorm.com/api_reference.html?highlight=to_dict#Entity.to_dict
Alexander
The limitation of to_dict is may be hard to convert deep nested structures
Lucky
I understiood not at all?
Alexander
It should return attribute values as a dict values. It does not convert them to JSON-compatible values automatically. But when you call json.dumps you can pass default argument which is a function. You can pass a function which convert a timestamp to suitable representation
Lucky
Right. Awesome once again
Lucky
BTW, how is that migration mode going on?
Anonymous
awesome, thanks!
Alexander
It is in process, we have some tests which a fail currently and want to fix them before release
Alexander
The base functionality works already
Lucky
Cuz I made a (for me) non-trivial DB change so I wanted to ask.
Lucky
This is my old `Tag` schema https://editor.ponyorm.com/user/luckydonald/Tags_4
Lucky
This is what I actually want https://editor.ponyorm.com/user/luckydonald/Tags
Lucky
The difference is that I moved sticker into a subclass, and added anotherone with a stickerpack attribute
Alexey
an example of to_dict and json.dumps
Lucky
The difference is that I moved sticker into a subclass, and added anotherone with a stickerpack attribute
What I understood, Pony does that in one big table, distinguising it with a special row, telling it to be a specific class.
Alexey
def account_page(): user = get_current_user() projects = Project.select(lambda p: p.user == user).order_by(desc(Project.updated_at)) account = user.to_dict(exclude=['id', 'password', 'balance']) return json.dumps({ 'account': account, 'projects': [dict(p.to_dict(exclude=['id', 'user', 'data'])) for p in projects] }, default=json_handler)
Alexey
def json_handler(obj): if hasattr(obj, 'isoformat'): return obj.isoformat() elif isinstance(obj, UUID): return str(obj) else: raise TypeError("Unserializable object {} of type {}".format(obj, type(obj)))
Lucky
What I understood, Pony does that in one big table, distinguising it with a special row, telling it to be a specific class.
So, I'd need to add a row for that? If I remember correctly thats type "text" and contains a string of the class name? In that migration I would need to fill in "StickerTag", right? (I still have the sticker attribute) And add another pack field?
Alexander
I think that first version of migration tool will not support such a changes which move attributes between subclasses. But this migration is actually simple. The first change is adding classtype system column which Pony uses to distinguish between subclasses. The second one is adding pack column for PackTag.pack relation. So the SQL for migration looks like (I assume PostgreSQL is used): alter table "tag" add column "classtype" text; update "tag" set "classtype" = "StickerTag"; --for previous objects alter table "tag" add column "pack" int references "stickerpack" ("id");
Alexander
Yes, I think if you add default value it should work with previous code without problems
Lucky
Cool, because I have seperated everything between Dev and Production, well except the database :/ The DB is shared.
Alexander
Maybe it is better to have two different database copies for Dev and Prod
Alexander
That way you may be sure that you non-tested dev code does not delete all objects from the database
Lucky
Yes, definitly. Probably I'll learn that as soon as I fry up the DB. Couldn't find a way to easily export/import all the data, so I instead make periodically backups of the postgres folder... ... .. . and hope nothing bad happens... (Yeah that is terrible, I know)
Alexander
Maybe we need some dump/load functionality in Pony
Lucky
Not sure if that should be part of pony (or pony core at least)
Lucky
But It could indeed make switching Databases easy
Alexander
I think making backup of entire database is outside of Pony scope. But maybe we should have a method to save content of a known entities into a big JSON file and then to load data from that file
Alexander
That way it may be easier to populate a dev & test databases