Re: Dynamic app loading

2018-07-31 Thread Christian González
Hi Raphael,
> we are doing such a thing for quite a while in our open source project
> pretix[1].
Whow, I'm quite impressed. Never stumbled upon that. I'll recommend that
for some collegues (to use it...)
But about the internals: Nice, this was the first way I implemented that
as well, and maybe I will come back to that again. You have to restart
the server as well if you want to enable a plugin, right?

> [...]
> To discover apps/plugins, we rely on setuptools' entry point
> feature[2], which allows us to easily load all compatible apps
> installed in the local Python requirement.

>From a security POV, I thought: who hinders anyone to write malicious
code and provide an entry point for your system? maybe in a library you
install... (but this is merely a philosophic question... don't bother.)

* You (deprecatedly) searched for plugins in all installed apps, check
which one has a "PretixPluginMeta" attr. This is quite nice. I did just
by appname.startswith('foo'). Less pythonic... ;-)
But it's now replaced by entry points discovery. I had this too, (and
will maybe come back to it). Setuptools' entry points discovery is a bit
slow, but for the server start that doesn't matter, it's just once.
(except development, you'll have to restart your server often)
Your entrypoint is e.g. "pretix_pages=pretix_pages:PretixPluginMeta" - I
don't understand that - this is an inner class of PluginApp. How can
you  access it directly via the entry point? But generally I understand
the workflow.

* How do you use signals? e.g.

    @receiver(footer_link, dispatch_uid="pages_footer_links")
What does this mean? How do you pass this to your frontend? Could you
describe this in just a few words?

Really, I had about 70% of your system already (more or less) working)
in mine. And as I will proceed, I think I will come back to the same
system as well.
I'd like to add channels to the mix as well to enable a Vue frontend.
Instead of copying your code and forking the parts that I need, It would
be better OpenSource practice to maybe build a "plugin system" that is a
library and can be used of both - this is not very difficult IMHO,
b'cause most of it is already there.

Just tell me what you think about it - I can live with both - I just
think that stability is better if more projects rely on one library and
find security flaws and bugs alternatively ;-)

I have written a IMHO better plugin handler:
https://gitlab.com/nerdocs/medux/MedUX/blob/develop/medux/extensionsystem/__init__.py


It defines defined before to have custom attrs., like:

class URLPattern(Interface):
    def get_patterns(self):
        pass

and in the plugin, this way you can use any class and decorate it with

    @implements(URLPattern)
    class FooURLPattern:
    def get_patterns(self):
    return [path(...)]

And in Main urls.py:

for pattern in URLPattern:
    prl_patterns += pattern.get_patterns

This way all plugins can just "implement" predefined Interfaces, supereasy.


Greetings from Salzburg,
Christian
> [1] https://github.com/pretix/pretix
> [2] https://packaging.python.org/specifications/entry-points/
> [3]
> https://github.com/pretix/pretix/blob/master/src/pretix/settings.py#L264
> [4]
> https://github.com/pretix/pretix/blob/master/src/pretix/base/signals.py#L21
> [5]
> https://github.com/pretix/pretix/blob/master/src/pretix/multidomain/maindomain_urlconf.py#L23
> [6]
> https://github.com/pretix/pretix/blob/master/src/pretix/multidomain/plugin_handler.py
> [7] https://docs.pretix.eu/en/latest/development/api/index.html

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/80179385-e006-c24c-5cd4-5b27d43b140e%40nerdocs.at.
For more options, visit https://groups.google.com/d/optout.


signature.asc
Description: OpenPGP digital signature


Re: PostgreSQL aggregation and views through unmanaged models

2018-07-31 Thread vojtech.bocek via Django developers (Contributions to Django itself)
Hello,
the fix for https://code.djangoproject.com/ticket/27241 caused significant 
performance drop for my project, because it pretty much prevents posgresql 
from using indexes on the particular query. I use unmanaged tables because 
Django is used to display data from another project's database, so it has 
just read-only access to the database and I don't want to create any 
migrations for it.

Another solution I came up while writing this post would be to replace the
> feature flag by a callable that takes a model as a single parameter and 
> returns
> whether or not the optimization can be performed against it. The default
> implementation would return `mode._meta.managed` but it would make it 
> easier for
> users affected by this to override in order to opt-in or out based on their
> application logic.
>

This would be perfect for my (arguably niche) use case. Should I try to 
prepare a patch?

On Monday, May 22, 2017 at 5:05:38 AM UTC+2, charettes wrote:
>
> Hello fellow developers,
>
> As some of you may know PostgreSQL 9.1 added support for GROUP'ing BY
> selected table primary keys[0] only. Five years ago it was reported[1] that
> Django could rely on this feature to speed up aggregation on models backed
> up by tables with either many fields or a few large ones.
>
> Being affected by this slow down myself I decided to dive into the ORM 
> internals
> and managed to get a patch that made it in 1.9[2] thanks to Anssi's and 
> Josh's
> review[3].
>
> One subtle thing I didn't know back in the time is that PostgreSQL query 
> planner
> isn't able to introspect database views columns' functional dependency 
> like it
> does with tables and thus prevents the primary key GROUP'ing optimization 
> from
> being used.
>
> While Django doesn't support database views officially it documents that
> unmanaged models can be used to query them[4] and thereby perform 
> aggregation on
> them and generating an invalid query.
>
> This was initially reported as a crashing bug 9 months ago[5] and the 
> consensus
> at this time was that it was an esoteric edge case since there was few 
> reports
> of breakages and it went off my radar. Fast-forward to a month ago, this is
> reported again[6] and it takes the reporter quite a lot of effort to 
> determine
> the origin of the issue, pushing me to come up with a solution as I 
> introduced
> this behavior.
>
> Before Claude makes me realize this is a duplicate of the former report 
> (which I
> completely forgot about in the mean time) I implement a patch and commit 
> it once
> it's reviewed [7].
>
> When I closed the initial ticket as "fixed" the reporter brought to my 
> attention
> that this was now introducing a performance regression for unmanaged models
> relying on aggregation and that we should document how to disable this
> optimization by creating a backend subclass as a workaround instead.
>
> In my opinion the current situation is as follow. The optimization 
> introduced a
> break in backward compatibility in 1.9 as we've always documented that 
> database
> views could be queried against using unmanaged models. If this issue had 
> been
> discovered during the 1.9 release cycle it would have been eligible for a
> backport because it was a bug in a newly introduced feature. Turning this
> optimization off for unmanaged models by assuming they could be views is 
> only
> going to degrade performance of queries using unmanaged models to perform
> aggregation on tables with either a large number of columns or large 
> columns
> using PostgreSQL.
>
> Therefore I'd favor we keep the current adjustment in the master branch as 
> it
> restores backward compatibility but I don't have strong feelings about 
> reverting
> it either if it's deemed inappropriate.
>
> Another solution I came up while writing this post would be to replace the
> feature flag by a callable that takes a model as a single parameter and 
> returns
> whether or not the optimization can be performed against it. The default
> implementation would return `mode._meta.managed` but it would make it 
> easier for
> users affected by this to override in order to opt-in or out based on their
> application logic.
>
> Thank you for your time,
> Simon
>
> [0] https://www.postgresql.org/docs/9.1/static/sql-select.html#SQL-GROUPBY
> [1] https://code.djangoproject.com/ticket/19259
> [2] 
> https://github.com/django/django/commit/dc27f3ee0c3eb9bb17d6cb764788eeaf73a371d7
> [3] https://github.com/django/django/pull/4397
> [4] https://docs.djangoproject.com/en/1.11/ref/models/options/#managed
> [5] https://code.djangoproject.com/ticket/27241
> [6] https://code.djangoproject.com/ticket/28107
> [7] 
> https://github.com/django/django/commit/daf2bd3efe53cbfc1c9fd00222b8315708023792
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to