Reputation: 249
I'm trying to determine how to construct a query. I have two models from an external database that I"m trying to import into a different schema. The source data has three models:
class Group(model):
...
name = models.CharField()
class Person(model):
...
name = models.CharField()
class Membership(model):
...
status = models.CharField()
created_date = models.DateTimeField()
modified_date = models.DateTimeField()
person = models.ForeignKey(
'Person',
related_name='memberships',
)
group = models.ForeignKey(
'Group',
related_name='memberships',
)
In the Memberships, I have fields representing the person and band, with create dates and update dates, as well as other relevant data.
Here's the problem: the Membership rows don't have any field that represents which is the canonical record, and they mix and match persons and dates and other data.
What I'm doing currently is taking all the Memberships for a given band, running distinct on them for the combination of band and person and using those results to query the Memberships again for the latest instance of each particular combination. While this works, as you might imagine is is unspeakably slow and I know there must be a better way.
So I'm looking for how to use some of the advanced django query expressions (Window? Over, F-expressions?) to get this done as much as possible on the database.
Here is the code that is getting me the records I want:
groups = (the groups I want)
for group in groups:
unique_members = group.members.values(
'person',
'group',
).distinct()
for member in members:
current_member = group.members.filter(
person__id=member['person'],
group__id=member['structure'],
).lastest('created_date', 'modified_date')
With current_member
being the most recent membership entry for that unique person/group combination.
So for a list of memberships like this:
Person Group Created Status
John Lennon Beatles 1960-01-01 Current
Paul McCartney Beatles 1960-01-01 Current
Pete Best Beatles 1960-01-01 Expired
George Harrison Beatles 1960-01-01 Current
Ringo Starr Beatles 1962-01-01 Expired
Pete Best Beatles 1964-01-01 Expired
Ringo Starr Beatles 1966-01-01 Current
I'd want the following list:
John Lennon Beatles 1960-01-01 Current
Paul McCartney Beatles 1960-01-01 Current
Pete Best Beatles 1964-01-01 Expired
George Harrison Beatles 1960-01-01 Current
Ringo Starr Beatles 1966-01-01 Current
Generated from a single query.
Thanks!
Upvotes: 0
Views: 119
Reputation: 1273
You can first order your members query by the desired entry then get the distict values. This question may help you:
Django query: get the last entries of all distinct values by list
Upvotes: 1