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

Any plans for supporting generic foreign keys? #121

Closed
sigurdga opened this issue Oct 17, 2012 · 10 comments
Closed

Any plans for supporting generic foreign keys? #121

sigurdga opened this issue Oct 17, 2012 · 10 comments

Comments

@sigurdga
Copy link

After spending a day to see if peewee is suitable for my project(s), I cannot see any way to use generic foreign keys, or any way to do a query that will join on explicit column names and values.

Tags would be a natural case for this, when you want to refer to "content type" and "object id" to be able to use tags all over without creating a lot of tables.

Django describes it as content types: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/

The way I tried to do it was to have a CharField and an IntegerField, where the CharField contains the table name and the IntegerField the id. But I cannot figure out how to do the queries, as I am not able to join two tables without a foreign key.

@coleifer
Copy link
Owner

If you want generic foreign keys, I would consider adding them as a part of the "playhouse" package. You're right, they hinge on having some sort of additional framework that maps database entries to model classes (or other tables, if you prefer). I'll take a look at this, as I have (ab)used django's GFKs a bit.

@coleifer
Copy link
Owner

What do you think about an API like this:

class Tag(Model):
    tag = CharField()
    object_type = CharField(null=True)
    object_id = IntegerField(null=True)
    object = GFKField('object_type', 'object_id')

class Blog(Model):
    tags = ReverseGFK(Tag, 'object_type', 'object_id')

tag.object -> should be a blog
blog.tags -> select query of tags for ``blog`` instance
Blog.tags -> select query of all tags for Blog instances

Code: https://github.com/coleifer/peewee/blob/feature/gfk/playhouse/gfk.py

Branch: https://github.com/coleifer/peewee/tree/feature/gfk

@sigurdga
Copy link
Author

Wow! I'm eager to try this out tomorrow. It looks like this approach should work, and I hope it will when testing it. I'll let you know how it works for me.

Thanks a million!

@coleifer
Copy link
Owner

merged into master

@sigurdga
Copy link
Author

Great! I have just checked it out and it works perfect with the rest of my code. Peewee query syntax is very self explaining and easy to remember. And it is a lot easier to understand your little example code above than the corresponding Django documentation.

@wonderbeyond
Copy link

I've made a simple generic foreign key implementation: https://gist.github.com/wonderbeyond/0e1f402b7595e0b4f9f653260fed029c#file-index-md

@coleifer
Copy link
Owner

Thanks for sharing @wonderbeyond -- this module was removed in 3.0.

@crazy2k
Copy link

crazy2k commented Nov 11, 2019

Why was this removed? Is there some other "official" way to handle the use case that @wonderbeyond's code solves?

@coleifer
Copy link
Owner

Why was this removed?

In my opinion, it's a gross hack and really does not belong in production-worthy code. It cannot be optimized in a generic way. It's only helpful for the simplest use-cases, but is very easy to have a footgun moment. A well-designed schema will obviate the need for this.

Implementation-wise, it requires a centralized registry of sorts to indicate the "content-type" that an arbitrary identifier references.

Also muddies the water in terms of introspection.

@crazy2k
Copy link

crazy2k commented Nov 11, 2019

Thanks for the reply!

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

No branches or pull requests

4 participants