Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding sugar via patching model classes - a discussion topic #27

Open
rudyryk opened this issue May 8, 2016 · 3 comments
Open

Adding sugar via patching model classes - a discussion topic #27

rudyryk opened this issue May 8, 2016 · 3 comments
Labels

Comments

@rudyryk
Copy link
Member

rudyryk commented May 8, 2016

Peewee's design is based on maximum simplicity concept, there is not so much of magic in implementation and no "black" magic at all, as I can see. And peewee provides the exceptionally clean and powerful interface -- it's far cleaner than the one for sqlAlchemy and more powerful that the Django's one -- having probably the best balance between simplicity and power.

The design goal for the peewee-async project is to play nice with peewee core conforming its approach and add extra facilities for async programming. That is why the current implementation does not apply any real black magic as well. Yes we rely on some internal logic, but NO, we don't perform any kind of patching!

I like this approach, but probably it would be acceptable to add some more sugar so we could get less verbose async calls.

For now, we have a high-level API via the Manager class and can write code like that:

# `objects` is the `Manager` class instance
user = await objects.get(User, id=user_id)
posts = await objects.execute(Post.select().where(
    Post.is_published == True,
    Post.author == user))

Looks like OK and actually, we can implement nicer interface at the application level, for example:

class UsersManager:
   # ...

   async def get(cls, user_id):
        return (await cls.objects.get(User, id=user_id))

and so on.

So I don't think it's crucial to add more interface methods to the peewee-async, but I'm considering to add some sugar via Manager.extend() method: https://github.com/05bit/peewee-async/blob/extend/peewee_async.py#L115 It will allow to leave the Manager under the hood in the most cases and write like that:

user = await User.get_async(id=user_id)
posts = await Post.execute_async(Post.select().where(
    Post.is_published == True,
    Post.author == user))

-- well, not ideal but simpler as we don't need to pass around objects and keep in mind that we need it every time.

I hope to hear some critics and suggestions on that, so we could refine the idea or left it out.

@julien-duponchelle
Copy link

It seem more like standard peewee usage

@rudyryk
Copy link
Member Author

rudyryk commented Aug 29, 2016

@noplay Yes, I'm thinking on more "peewee-like" interface, but I'm not a big fan of reusing by subclassing - so the ideal solution should work without modification of models.

@rudyryk
Copy link
Member Author

rudyryk commented Sep 20, 2016

Another approach is to add optional mixin class, so we don't always need to patch models but just add mixin via inheritance. Not perfect, but still better than patching.

Unfortunately, thare are no established standards yet for providing both sync and async interfaces in classes. I'm still not sure about suffixing for methods with _async.

Probably, it's possible to override base query classes so they will support await and we could just run await MyModel.select().where(MyModel.id == 1). But this is potentially possible only for lazy query methods, e.g. get() is not lazy and will just run synchronously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants