Models

class heroku_connect.db.models.HerokuConnectModel(*args, **kwargs)[source]

Base model for Heroku Connect enabled ORM models in Django.

Example::

from heroku_connect.db import models as hc_models

class MyCustomObject(hc_models.HerokuConnectModel):

sf_object_name = ‘My_Custom_Object__c’

custom_date = hc_models.DateTime(sf_field_name=’Custom_Date__c’)

Note

Subclasses have Meta.managed set to False.

A default value for Meta.db_table is set based on settings.HEROKU_CONNECT_SCHEMA and sf_object_name.

Note

A model mixin must inherit from Meta.managed not .HerokuConnectModel. Only the final (not abstract) models should inherit from .HerokuConnectModel otherwise build-in fields will clash.

Warning

The Salesforce User and RecordType objects have no IsDeleted field. Therefore if sf_object_name is set to User or RecordType the Django ORM representation does not have this field either. You can add the IsActive field to your User or RecordType object, but it is not required by Heroku Connect.

classmethod get_heroku_connect_table_name()[source]

Return the table name (without schema) associated with a model class.

Parameters:

model_cls – A connected model class object

Raises:

LookupError – if no table name is associated with the given class

sf_access = 'read_only'[source]

Heroku Connect Object access level.

Access to Heroku Connect tables can be either read or write. Read will only sync from Salesforce to PostgreSQL where write will sync both ways.

Default value is read_only.

Accepted values:
  • read_only

    Synchronize only from Salesforce to PostgreSQL.

  • read_write

    Synchronize both ways between Salesforce and PostgreSQL.

sf_notify_enabled = False[source]

Use the Salesforce Streaming API to trigger polls when data changes.

With event-based polling enabled, Heroku Connect will continue to poll at the set polling frequency.

sf_object_name = ''[source]

Salesforce object API name.

sf_polling_seconds = 600[source]

Poll frequency in seconds.

Default: 10 minutes

Model inheritance

Model inheritance in with Heroku Connect models is almost identical to Django’s Model inheritance feature. For example you can build model mixins as followed:

from heroku_connect.db import models as hc_models


class ExternalIDModelMixin(hc_models.HerokuConnectModel):
    sf_access = hc_model.READ_WRITE

    external_id = hc_models.ExternalID(sf_field_name='External_ID__c')

    class Meta:
        abstract = True


class MyModel(ExternalIDModelMixin):
    sf_object_name = 'My_Object__c'

    data = hc_models.Text(sf_field_name='Data__c')

Multi-table inheritance

Multi-table inheritance is a concept where each superclass is a model by itself. It allows building hybrid models that are partly managed by Heroku Connect partly by Django.

Example:

from django.db import models
from heroku_connect.db import models as hc_models


class SFObjectModel(hc_models.HerokuConnectModel):
    sf_object_name = 'My_Object__c'
    sf_access = hc_model.READ_WRITE

    external_id = hc_models.ExternalID(sf_field_name='External_ID__c')
    data = hc_models.Text(sf_field_name='Data__c')


class CompoundModel(SFObjectModel):
    hc_model = models.OneToOneField(SFObjectModel, on_delete=models.CASCADE,
                                    to_field='external_id', parent_link=True,
                                    db_constraint=False)
    more_data = models.TextField()

    class Meta:
        managed = True

In this scenario SFObjectModel is managed by Heroku Connect and CompoundModel a hybrid where CompoundModel.data is manged by Heroku Connect and CompoundModel.more_data is managed by Django.

Warning

You should use your own parent_link OneToOneField that points to the upsert-field of your parent Heroku Connect model as the id-field is not not guarantied in to be consistent.

It is also possible to have two concrete Heroku Connect models to Inherit from each other.

Signals

Standard Django model signals won’t be triggered for changes made on Salesforce, because Heroku Connect operates on a database-level. If you want to hook into to changes coming from Salesforce, there are several possible solutions: