Join results of subqueries in Django

Viewed 243

I'm implementing a distributed event store using Vector Clocks to establish a deterministic ordering of events.

I'm attempting to perform the following raw query using Django ORM:

   SELECT dev_snapshots.global_snapshot_id as snapshot_id, 
          dev_snapshots.environment_id, 
          dev_snapshots.clock,
          test_snapshots.environment_id,
          test_snapshots.clock
   FROM (
          SELECT
            global_snapshot_id,
            clock,
            environment_id
          FROM environment_snapshot
          WHERE environment_id = 'dev') dev_snapshots
     JOIN (
            SELECT
              global_snapshot_id,
              clock,
              environment_id
            FROM environment_snapshot
            WHERE environment_id = 'test') test_snapshots
       ON dev.global_snapshot_id = test.global_snapshot_id
   ORDER BY dev_snapshots.clock, test_snapshots.clock

My models are as follows:

class Environment(models.Model):
    env_name = models.TextField(primary_key=True)
    current_clock = models.BigIntegerField()


class EnvironmentSnapshot(models.Model):
    global_snapshot = models.ForeignKey('GlobalSnapshot')
    environment = models.ForeignKey('Environment')
    clock = models.BigIntegerField()


class GlobalSnapshot(models.Model):
    id = models.AutoField(primary_key=True)   

Environment has a name and a counter value called clock.
EnvironmentSnapshot is a snapshot of a single Environment's clock value during a single GlobalSnapshot.
GlobalSnapshot collects EnvironmentSnapshots for all environments that exist at the time the GlobalSnapshot is created.

The idea is to sort all the GlobalSnapshots first by the clock value of the "dev" Environment, then by the clock value of the "test" Environment to get a deterministic order of events regardless of when the event was received. GlobalSnapshot is eventually joined to an event that is recorded in the event store.

I've looked into Query.join() in Django but it doesn't seem very well documented, or even meant for end users to use.

Is there a way for Django ORM to do this, or will I simply need to construct a raw query for Django to execute?

0 Answers
Related