Skip to content

Instantly share code, notes, and snippets.

@nickpeihl
Last active January 27, 2022 11:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickpeihl/4692753 to your computer and use it in GitHub Desktop.
Save nickpeihl/4692753 to your computer and use it in GitHub Desktop.
Expose and Edit an ArcSDE 10.1 Versioned View in PostgreSQL using Django
## Tested using ArcSDE 10.1 and PostgreSQL 9.1/PostGIS 2.0
## Other database types and software versions need testing.
## Prior to use you must create the Versioned View on the
# feature class you want to edit. You must also create the
# ArcSDE version you want to use for the edits.
# In Settings.py
# ...
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': '',
'HOST': '',
'USER': '',
'PASSWORD': '',
'OPTIONS': {
# Set autocommit to true so transactions don't interfere with
# other concurrent users
'autocommit': True
}
}
}
## In models.py
from django.contrib.gis.db import models
from django.dispatch import receiver
from django.db.models.signals import pre_init, post_init, pre_save, post_save
from django.contrib.gis.db.models.query import GeoQuerySet
def set_db_version(version='sde.DEFAULT'):
""" Set the ArcSDE Version for queries and
edits. Version argument must include the version
owner's name and the version name (e.g. JDoe.JohnDoe).
Default version is sde.DEFAULT.
The result of the SQL statement must be equal to 0 (zero).
Any other result means the version doesn't exist or
cannot be found and we throw an exception."""
from django.db import connection
cursor = connection.cursor()
# Data retrieval operation - no commit required
sql = "select sde.sde_set_current_version('%s')" % version
cursor.execute(sql)
row = cursor.fetchone()
if row[0] <> 0:
raise ValueError("Version %s not found" % version)
cursor.close()
class SdeVersionedViewManager(models.GeoManager):
""" Custom model manager for Versioned Views. Overrides the
get_query_set method by first setting the ArcSDE version
to query."""
use_for_related_fields = True
def get_query_set(self):
version_set = set_db_version(version='VersionOwner.MyEditVersion')
return GeoQuerySet(self.model, using=self._db)
class MyVersionedFeatureClassModel(models.Model):
""" Model of a Versioned View in the ArcSDE geodatabase.
In Meta options set Managed=False to avoid issues with
manage.py syncdb. Also set the db_table to point to the
versioned view (usually MyFeatureClass_vw).
Django doesn't have built-in support for accessing tables
not in the public schema. A hack to fix this is prefacing
the Versioned View name with the schema name and an escaped
period (e.g. db_table='MySchema\".\"MyVersionedView').
Be sure to substitute the model manager with the
SdeVersionedViewManager defined above
(e.g. objects = SdeVersionedViewManager())."""
objectid = models.IntegerField(primary_key=True)
# All attribute fields go here
sde_state_id = models.BigIntegerField()
shape = models.PolygonField(srid=4326, blank=True, null=True)
objects = SdeVersionedViewManager()
class Meta:
db_table = 'MySchema\".\"MyVersionedView'
managed = False
# Receive Django Signals for pre_save and post_save on the model
@receiver(pre_save, sender=MyVersionedFeatureClassModel)
def start_edit_session(version='VersionOwner.MyEditVersion', **kwargs):
""" Prior to saving edits to the model, we need to
start the edit session in ArcSDE.
The cursor.execute method by default adds single quotes
to the variable name so we don't need to."""
from django.db import connection
cursor = connection.cursor()
# Data retrieval operation - no commit required
cursor.execute("SELECT sde.sde_edit_version(%s, 1)", [version])
cursor.close()
@receiver(post_save, sender=MyVersionedFeatureClassModel)
def stop_edit_session(version='VersionOwner.MyEditVersion', **kwargs):
""" After saving the edits to the model we must
stop the edit session in ArcSDE.
The cursor.execute method by default adds single quotes
to the variable name so we don't need to."""
from django.db import connection
cursor = connection.cursor()
# Data retrieval operation - no commit required
cursor.execute("SELECT sde.sde_edit_version(%s,2)", [version])
cursor.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment