Inner joins with timestamps and no foreign key in Django ORM

Viewed 69

Django documentation states to check the ORM before writing raw SQL, but I am not aware of a resource that explains how to perform inner joins between tables without foreign keys, something that would be relatively simple to execute in a few lines of SQL.

Many of the tables in my database need to be joined by time-related properties or intervals. For example, in this basic example I need to first take a subset of change_events, and then join a different table ais_data on two separate columns:

models.py

class AisData(models.Model):
    navstatus = models.BigIntegerField(blank=True, null=True)
    start_ts = models.DateTimeField()
    end_ts = models.DateTimeField(blank=True, null=True)
    destination = models.TextField(blank=True, null=True)
    draught = models.FloatField(blank=True, null=True)
    geom = models.PointField(srid=4326)
    imo = models.BigIntegerField(primary_key=True)
    
        class Meta:
        managed = False
        db_table = 'ais_data'
        unique_together = (('imo', 'start_ts'),)


class ChangeEvent(models.Model):
    event_id = models.BigIntegerField(primary_key=True)
    imo = models.BigIntegerField(blank=True, null=True)
    timestamp = models.DateTimeField(blank=True, null=True)


    class Meta:
        managed = False
        db_table = 'change_event'

First I take a subset of change_events which returns a QuerySet object. Using the result of this query, I need to get all of the records in ais_data that match on imo and timestamp - so the raw SQL would look exactly like this:


WITH filtered_change_events AS (

SELECT * FROM change_events WHERE timestamp BETWEEN now() - interval '1' day and now()
)

SELECT fce.*, ad.geom FROM filtered_change_events fce JOIN ais_data ad  ON fce.imo = ad.imo AND fce.timestamp = ad.start_ts

views.py

from .models import ChangeEvent
from .models import AisData
from datetime import datetime, timedelta

start_period = datetime.now() - timedelta(hours=24)
end_period = datetime.now()

subset_change_events = ChangeEvent.filter(timestamp__gte=start_period,
                                          timestamp__lte=end_period)

#inner join 

subset_change_events.filter()?                                          

How would one write this relatively simple query using the language of Django ORM? I am finding it difficult to make a simple inner join on two columns in without using a foreign key? Any advice or links to resources would be helpful.

0 Answers
Related