Last active
January 27, 2022 11:06
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## 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