Lucky
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
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
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
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!
Lucky
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
Lucky
Alexander
The limitation of to_dict is may be hard to convert deep nested structures
Lucky
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
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)))
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");
Lucky
Lucky
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
Lucky