-
Notifications
You must be signed in to change notification settings - Fork 95
Reverse lookup #599
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
base: master
Are you sure you want to change the base?
Reverse lookup #599
Conversation
|
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #599 +/- ##
==========================================
+ Coverage 88.42% 92.54% +4.12%
==========================================
Files 117 118 +1
Lines 8653 8772 +119
==========================================
+ Hits 7651 8118 +467
+ Misses 1002 654 -348 ☔ View full report in Codecov by Sentry. |
|
Thanks for this! It looks very promising. |
|
Thanks. I used a lot of code (with some modifications) from M2M fields. I tried to use the best names of variables and methods. The main obstacle is that the user would have to enter |
|
Just wanted to note that there is interest in this functionality. Is there anything specific holding this back (from being merged)? Also I like how in peewee one can just set the |
piccolo/columns/reverse_lookup.py
Outdated
| i._meta.name | ||
| for i in reverse_lookup_table._meta.foreign_key_columns | ||
| ] | ||
| return fk_columns.index(self.table._meta.tablename) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we compare column names with table names here. They don't have to match. I think instead of
Manager.artists(table=Manager)
it would be better to be able to specify:
Manager.artists(column="manager")
Since the column that is used for the reverse lookup doesn't change(?), I think it would be best if we could also specify it in the ReverseLookup constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@powellnorma Thanks for your interest and review. It's been a while since I wrote this code, but if I remeber it has to be a table because we refer to the foreign key of parent table later in the code. We need this function to find the foreign key column index if there are multiple foreign keys per single table.
I haven't had chance to review it yet - but I agree that it's a feature we need. |
piccolo/columns/reverse_lookup.py
Outdated
| reverse_lookup_fk_table_name = ( | ||
| reverse_lookup_table._meta.foreign_key_columns[ | ||
| self.foreign_key_columns_index | ||
| ]._meta.name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think instead of _meta.name it should be _meta.table._meta.tablename. Otherwise reverse_lookup_fk_table_name is a column name
piccolo/columns/reverse_lookup.py
Outdated
| SELECT | ||
| "{reverse_lookup_table_name}"."{column_name}" | ||
| FROM {reverse_select} | ||
| ) AS "{reverse_lookup_table_name}s" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use AS "{original_column_name}s". The table must give us that name. See m2m.py:
piccolo/piccolo/columns/m2m.py
Line 93 in 14012e5
| ) AS "{m2m_relationship_name}" |
|
@dantownsend It would be great if you could find the time to review this. @powellnorma This code works and passes all tests. If you think that things should be changed, it would be best after Daniel's review. Thank you both. |
piccolo/columns/reverse_lookup.py
Outdated
| reverse_select = f""" | ||
| "{reverse_lookup_table_name}" | ||
| JOIN "{reverse_lookup_fk_table_name}" "inner_{reverse_lookup_fk_table_name}" ON ( | ||
| "{reverse_lookup_table_name}"."{reverse_lookup_fk}" | ||
| = "inner_{reverse_lookup_fk_table_name}"."{reverse_lookup_pk}" | ||
| ) WHERE "{reverse_lookup_table_name}"."{reverse_lookup_fk}" | ||
| = "{reverse_lookup_fk_table_name}"."{reverse_lookup_pk}" | ||
| """ # noqa: E501 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this JOIN here? Isn't the following enough?
reverse_select = f"""
"{reverse_lookup_table_name}"
WHERE "{reverse_lookup_table_name}"."{reverse_lookup_fk}"
= "{reverse_lookup_fk_table_name}"."{reverse_lookup_pk}"
"""
I haven't looked, but I guess the tests always use a ForeignKey named the same as the referenced Table. As e.g. here: class Manager(Table):
name = Varchar()
class Artist(Table):
name = Varchar()
manager = ForeignKey(Manager)But if this is not true, as e.g. here: class MainManager(Table):
name = Varchar()
class Artist(Table):
name = Varchar()
manager = ForeignKey(MainManager)the sections I pointed lead to errors / wrong queries |
|
When I query an M2M field of the referenced table, I get: AttributeError: type object 'M2MSelect' has no attribute 'value_type' |
Make it work when the ForeignKey is named differently than the referenced Table.
|
I have fixed the parts that I reviewed on my branch However querying an M2M field (of the referenced table) seems to be rather slow at the moment. When I set |
I'm sorry, but I don't understand. How can we refer to a table that doesn't exist. Shouldn't it be like this class MainManager(Table):
name = Varchar()
class Artist(Table):
name = Varchar()
manager = ForeignKey(MainManager)I want to try your branch. In my reverse lookup attempt I use class Manager(Table):
name = Varchar()
bands = ReverseLookup(
LazyTableReference("Band", module_path=__name__),
)
class Band(Table):
name = Varchar()
manager = ForeignKey(Manager)
# query for all managers bands
query = await Manager.select(
Manager.name, Manager.bands(Band.name, as_list=True, table=Manager)
)Can you show me how to write a table schema and an example query because right now I get |
The example I gave was wrong, I corrected it. What I meant was a situation in which the column name (of the foreign key) has a different name than the table that it refers to
Like this: class MainManager(Table):
name = Varchar()
artists = ReverseLookup(LazyTableReference("Artist", module_path=__name__), "manager")
class Artist(Table):
name = Varchar()
manager = ForeignKey(MainManager)
# select:
await MainManager.select(MainManager.artists(Artist.name)) |
You are right, it doesn't work if the column is different from the table name. I tried to use
This also doesn't work. Raise |
Hm, for me that example works. I (already) made changes so that |
|
Sorry, that was my mistake. I tried everything from scratch because I probably messed something up and you are right, the tests from my PR pass with your code. |
|
Hello, thank you for this lib, I plan to use it for an important sized project, and this feature is mandatory to me as it brings many benefits.
Python 3.13 has been supported now. Best regards |
|
@sam2x I don't know if that makes sense to you, but you can try using the unofficial branch (until everything is officially supported). The link contains an explanation and how to use it. Hope that helps. |
|
Hey, any updates on this feature ? I still use the PR, but would be great to have in the master piccolo orm. As far i can see the PR is still doing great job in terms of integration over all this year piccolo's updates. Best |
|
@dantownsend Please it has been 3years now. Can you share your feedbacks on this or if uncomfortable the reasons this patch isn't yet applied in the master branch ? Thank you |
|
@sam2x I'm glad you find reverse lookup useful. I've created a branch that I update regularly (to keep it in sync with the master branch). This branch is not official and I know is not perfect, but it does contain some important features that are not in the main branch. |
Related to #378. Prototype for reverse foreign key lookup. Any suggestions and help are welcome. If I missed the point or it's not a good api design feel free to close PR.
Usage of reverse FK lookup: