def default_db_entities(self, **kwargs): """ Project specific SACOG additional db_entities :param default_dict: :return: """ project = self.config_entity # The DbEntity keyspace. These keys have no prefix Key = ScagDmDbEntityKey # The Behavior keyspace behavior_key = BehaviorKey.Fab.ricate # Used to load Behaviors defined elsewhere get_behavior = lambda key: Behavior.objects.get(key=behavior_key(key)) return super(ScagDmProjectFixture, self).default_db_entities() + [ update_or_create_db_entity( project, DbEntity( name='SCAG Existing Land Use Parcels 2012', key=Key.EXISTING_LAND_USE_PARCELS_2012, feature_class_configuration=FeatureClassConfiguration( abstract_class=ExistingLandUseParcel, import_from_db_entity_key=Key. REGION_EXISTING_LAND_USE_PARCELS, filter_query=dict(city=project.name), fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_lu'))), feature_behavior=FeatureBehavior( behavior=get_behavior('reference')), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity( key=Key.CITY_BOUNDARY, feature_class_configuration=FeatureClassConfiguration( abstract_class=CityBoundary, import_from_db_entity_key=Key.REGION_CITY_BOUNDARY, filter_query=dict(city=project.name), use_for_bounds=True), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection.polygon_to_centroid ), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])) ]
def complete_or_create_feature_class_configuration( self, feature_class_configuration, **overrides): """ Clones the given feature_class_configuration to make it specific to the ConfigEntity If the feature_class_configuration is null a simple one is created :param feature_class_configuration: Used for the basis of cloning from another DbEntity, or as the preconfigured instance that was defined in an initializer, such as default_project.py :param overrides: Override anything in the feature_class_configuration. This is used for cloning when we need to specify generated=YES, source_from_origin_layer_selection=True, etc """ if self.db_entity and self.db_entity.no_feature_class_configuration: # If nothing is passed it means that the DbEntity doesn't represent a feature table, e.g. background imagery return None key = self.db_entity.key if self.db_entity else self.DETACHED_FROM_DB_ENTITY return FeatureClassConfiguration(**merge( dict( # Indicates that the configuration was generated by introspecting a table, rather than by deliberate configuration generated=False, # Indicates that the features should be created from an origin LayerSelection features. source_from_origin_layer_selection=False, # The origin Layer id origin_layer_id=None, # The user of the origin layer origin_user=None, # The default data_importer for features # The default imports based on the url of the db_entity--usually a special database url data_importer=None, ), # Override the above with any configured attributes merge(feature_class_configuration. __dict__, overrides) if feature_class_configuration else {}, # Override or define ConfigEntity specific attributes dict( key=key, # The scope is the id of the config_entity scope=self.config_entity and self.config_entity.id, # The config_entity id scopes the geography table, except for scenarios which # always use their Project config_entity id as the scope geography_scope=self.config_entity.id, schema=self.config_entity.schema(), class_attrs=merge( feature_class_configuration. class_attrs if feature_class_configuration else {}, { 'config_entity__id': self.config_entity.id, 'override_db': self.config_entity.db, 'db_entity_key': key }), ) if self.config_entity else dict( # Abstract case key=key, class_attrs=merge( feature_class_configuration. class_attrs if feature_class_configuration else {}, {'db_entity_key': key}))))
def generate_configuration(self, fields=[]): """ Creates a feature_class_configuration for db_entities not pre-configured, in other words, those that were uploaded. """ # Use the pk for the source_id_column primary_key_fields = filter(lambda field: field.primary_key, fields) # Use the existing primary key or default to the default Django one # The former case applies to imported tables that have primary keys, the latter to tables that are # created by Django source_id_column = primary_key_fields[ 0].name if primary_key_fields else 'id' return self.complete_or_create_feature_class_configuration( FeatureClassConfiguration( fields=fields, source_id_column=source_id_column, # Generated tells us that the feature_class_configuration wasn't pre-configured in code generated=True))
def clone_db_entity_and_interest_for_result(self, config_entity, existing_db_entity_interest, reference_db_entity_key, **kwargs): """ Clone the selected db_entity of key reference_db_entity and replace any of its attributes with those specified in **kwargs. **kwargs should contain a unique key property :param config_entity :param existing_db_entity_interest: The existing DbEntityInterest if one exists :param reference_db_entity_key: key of the DbEntity to clone :param kwargs: replacement values containing at the very least 'key' :return: The DbEntityInterest which references the cloned db_entity """ source_db_entity = config_entity.computed_db_entities().get( key=reference_db_entity_key) # Avoid circular reference from footprint.main.publishing.db_entity_publishing import clone_or_update_db_entity_and_interest db_entity_interest = clone_or_update_db_entity_and_interest( config_entity, source_db_entity, DbEntity(**merge( kwargs, dict(feature_class_configuration=FeatureClassConfiguration( **merge( source_db_entity.feature_class_configuration.__dict__, dict(feature_class_owner=reference_db_entity_key))), ))), existing_db_entity_interest=existing_db_entity_interest, override_on_update=True) # Run this manually here. It should be triggered by saving the DbEntity, but something # is disabling the publisher # TODO the DbEntity publihser should be turned on here so this should be neeed from footprint.main.publishing.user_publishing import on_db_entity_post_save_user on_db_entity_post_save_user(None, instance=db_entity_interest) return db_entity_interest
def default_db_entities(self): """ Region specific db_entity_setups :param default_dict: :return: """ config_entity = self.config_entity parent_region_fixture = self.parent_fixture default_db_entities = parent_region_fixture.default_db_entities() # The DbEntity keyspace. These keys have no prefix Key = ScagDmDbEntityKey # The Behavior keyspace behavior_key = BehaviorKey.Fab.ricate # Used to load Behaviors defined elsewhere get_behavior = lambda key: Behavior.objects.get(key=behavior_key(key)) if isinstance(self.config_entity.parent_config_entity_subclassed, GlobalConfig): # Block the client-level region. We just want real regions return [] return default_db_entities + FixtureList([ update_or_create_db_entity( config_entity, DbEntity( name='2016 SCAG Existing Land Use Parcels', key=Key.REGION_EXISTING_LAND_USE_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=ExistingLandUseParcel, primary_geography=True, primary_key='source_id', primary_key_type='int', fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_lu16'))), feature_behavior=FeatureBehavior( behavior=get_behavior('reference')), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.FLOOD_ZONES, feature_class_configuration=FeatureClassConfiguration( abstract_class=FloodZones), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.ENDANGERED_SPECIES, feature_class_configuration=FeatureClassConfiguration( abstract_class=EndangeredSpecies), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.CPAD_HOLDINGS, feature_class_configuration=FeatureClassConfiguration( abstract_class=CpadHoldings), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.HABITAT_CONSERVATION_AREA, feature_class_configuration=FeatureClassConfiguration( abstract_class=HabitatConservationAreas), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.COUNTY_BOUNDARY, feature_class_configuration=FeatureClassConfiguration( abstract_class=CountyBoundary), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(name='2040 High Quality Transit Areas', key=Key.HIGH_QUALITY_TRANSIT_AREAS, feature_class_configuration=FeatureClassConfiguration( abstract_class=HighQualityTransitAreas), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(name='2040 High Quality Transit Corridors', key=Key.HIGH_QUALITY_TRANSIT_CORRIDORS, feature_class_configuration=FeatureClassConfiguration( abstract_class=HighQualityTransitCorridors), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(name='2040 Major Transit Stops', key=Key.MAJOR_TRANSIT_STOPS, feature_class_configuration=FeatureClassConfiguration( abstract_class=MajorTransitStops), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(name='2040 Transit Priority Areas', key=Key.TRANSIT_PRIORITY_AREAS, feature_class_configuration=FeatureClassConfiguration( abstract_class=TransitPriorityAreas), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.FARMLAND, feature_class_configuration=FeatureClassConfiguration( abstract_class=Farmland, related_fields=dict(farmland_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_farmland_definition.ScagDmFarmlandDefinition', related_class_join_field_name='farmland_code', source_class_join_field_name='scag_type'))), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection.polygon_to_centroid ), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.REGION_GENERAL_PLAN_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=GeneralPlanParcels, primary_key='source_id', primary_key_type='int', fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', # Use this for the resource type, since we don't want a client-specific resource URL # TODO not wired up yet resource_model_class_name= 'footprint.main.models.built_form.ClientLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_gp_code16'))), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=AttributeIntersection()), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.REGION_SPECIFIC_PLAN_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=SpecificPlanParcels, primary_key='source_id', primary_key_type='int', fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', resource_model_class_name= 'footprint.main.models.built_form.ClientLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_sp_code16'))), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=AttributeIntersection()), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.REGION_ZONING_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=ZoningParcels, primary_key='source_id', primary_key_type='int', fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', resource_model_class_name= 'footprint.main.models.built_form.ClientLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_zn_code16'))), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=AttributeIntersection()), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.REGION_ENTITLEMENT_PARCELS_2016, feature_class_configuration=FeatureClassConfiguration( abstract_class=EntitlementParcels, primary_key='source_id', primary_key_type='int', fields=dict()), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=AttributeIntersection()), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.REGION_SCENARIO_PLANNING_ZONES, feature_class_configuration=FeatureClassConfiguration( abstract_class=ScenarioPlanningZones, ), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(name='Sphere of Influence', key=Key.REGION_SPHERE_OF_INFLUENCE, feature_class_configuration=FeatureClassConfiguration( abstract_class=SphereOfInfluence, ), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.REGION_TIER2_TAZ, feature_class_configuration=FeatureClassConfiguration( abstract_class=Tier2Taz, ), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.CENSUS_TRACTS, feature_class_configuration=FeatureClassConfiguration( abstract_class=CensusTracts, ), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.SUB_REGION, feature_class_configuration=FeatureClassConfiguration( abstract_class=SubRegion, ), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.REGION_CITY_BOUNDARY, feature_class_configuration=FeatureClassConfiguration( abstract_class=CityBoundary, ), feature_behavior=FeatureBehavior( behavior=get_behavior('editable_feature'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), # update_or_create_db_entity(config_entity, DbEntity( # key=Key.BIKE_LANE, # feature_class_configuration=FeatureClassConfiguration( # abstract_class=BikeLane, # ), # feature_behavior=FeatureBehavior( # behavior=get_behavior('reference_layers_editable_attribute'), # intersection=GeographicIntersection.polygon_to_centroid # ), # _categories=[Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE)] # )), update_or_create_db_entity( config_entity, DbEntity(key=Key.SEA_LEVEL_RISE, feature_class_configuration=FeatureClassConfiguration( abstract_class=SeaLevelRise, ), feature_behavior=FeatureBehavior( behavior=get_behavior( 'reference_layers_editable_attribute'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])) ])
def default_db_entities(self): """ Scenarios define DbEntities specific to the Scenario. Creates a list a dictionary of configuration functionality. These are filtered based on whether the given scenario matches the scope in the configuration :return: """ project = self.config_entity.parent_config_entity_subclassed scenario = self.config_entity # The DbEntity keyspace. These keys have no prefix Key = ScagDmDbEntityKey # The Behavior keyspace behavior_key = BehaviorKey.Fab.ricate # Used to load Behaviors defined elsewhere get_behavior = lambda key: Behavior.objects.get(key=behavior_key(key)) return super(ScagDmScenarioFixture, self).default_db_entities() + map( lambda db_entity_dict: update_or_create_db_entity( scenario, db_entity_dict['value']), FixtureList([ dict( class_scope=BaseScenario, value=DbEntity( name='2016 SCAG Existing Land Use Parcels', key=Key.EXISTING_LAND_USE_PARCELS_2016, feature_class_configuration=FeatureClassConfiguration( abstract_class=ExistingLandUseParcel, import_from_db_entity_key=Key. REGION_EXISTING_LAND_USE_PARCELS, filter_query=dict(city=project.name), # primary_geography=True, # primary_key='source_id', # primary_key_type='int', fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_lu16'))), feature_behavior=FeatureBehavior( behavior=get_behavior('editable_feature')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.EDITABLE_LAYER) ])), dict( class_scope=BaseScenario, value=DbEntity( name='2016 SCAG General Plan Parcels', key=Key.GENERAL_PLAN_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=GeneralPlanParcels, primary_key='source_id', primary_key_type='int', import_from_db_entity_key=Key. REGION_GENERAL_PLAN_PARCELS, filter_query=dict(city=project.name), fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', # Use this for the resource type, since we don't want a client-specific resource URL # TODO not wired up yet resource_model_class_name= 'footprint.main.models.built_form.ClientLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_gp_code16') )), feature_behavior=FeatureBehavior( behavior=get_behavior('editable_feature'), intersection=AttributeIntersection()), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.EDITABLE_LAYER) ])), dict( class_scope=BaseScenario, value=DbEntity( name='2016 SCAG Specific Plan Parcels', key=Key.SPECIFIC_PLAN_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=SpecificPlanParcels, primary_key='source_id', primary_key_type='int', import_from_db_entity_key=Key. REGION_SPECIFIC_PLAN_PARCELS, filter_query=dict(city=project.name), fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', resource_model_class_name= 'footprint.main.models.built_form.ClientLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_sp_code16') )), feature_behavior=FeatureBehavior( behavior=get_behavior('editable_feature'), intersection=AttributeIntersection()), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.EDITABLE_LAYER) ])), dict(class_scope=BaseScenario, value=DbEntity( name='2016 SCAG Infill Parcels', key=Key.INFILL_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=InfillParcels, import_from_db_entity_key=Key. REGION_INFILL_PARCELS, filter_query=dict(city=project.name), ), feature_behavior=FeatureBehavior( behavior=get_behavior('editable_feature'), intersection=AttributeIntersection()), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.EDITABLE_LAYER) ])), dict( class_scope=BaseScenario, value=DbEntity( name='2016 SCAG Zoning Parcels', key=Key.ZONING_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=ZoningParcels, primary_key='source_id', primary_key_type='int', import_from_db_entity_key=Key. REGION_ZONING_PARCELS, filter_query=dict(city=project.name), fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.scag_dm.built_form.scag_dm_land_use_definition.ScagDmLandUseDefinition', resource_model_class_name= 'footprint.main.models.built_form.ClientLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='scag_zn_code16') )), feature_behavior=FeatureBehavior( behavior=get_behavior('editable_feature'), intersection=AttributeIntersection()), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.EDITABLE_LAYER) ])), dict(class_scope=BaseScenario, value=DbEntity( name='2016 SCAG Entitlement Parcels', key=Key.ENTITLEMENT_PARCELS_2016, feature_class_configuration=FeatureClassConfiguration( abstract_class=EntitlementParcels, primary_key='source_id', primary_key_type='int', import_from_db_entity_key=Key. REGION_ENTITLEMENT_PARCELS_2016, filter_query=dict(city=project.name), fields=dict()), feature_behavior=FeatureBehavior( behavior=get_behavior('editable_feature'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.EDITABLE_LAYER) ])), dict(class_scope=BaseScenario, value=DbEntity( key=Key.SCENARIO_PLANNING_ZONES, feature_class_configuration=FeatureClassConfiguration( abstract_class=ScenarioPlanningZones, import_from_db_entity_key=Key. REGION_SCENARIO_PLANNING_ZONES, filter_query=dict(city=project.name), ), feature_behavior=FeatureBehavior( behavior=get_behavior('editable_feature'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), dict(class_scope=BaseScenario, value=DbEntity( name='City/Tier2 TAZ', key=Key.TIER2_TAZ, feature_class_configuration=FeatureClassConfiguration( abstract_class=Tier2Taz, import_from_db_entity_key=Key.REGION_TIER2_TAZ, filter_query=dict(city=project.name), ), feature_behavior=FeatureBehavior( behavior=get_behavior('sed_editor_tool'), intersection=AttributeIntersection()), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.EDITABLE_LAYER) ])) ]).matching_scope(class_scope=self.config_entity and self.config_entity.__class__))
def default_db_entities(self, **kwargs): """ Region specific SACOG db_entity_setups :param default_dict: :return: """ config_entity = self.config_entity parent_region_fixture = self.parent_fixture default_db_entities = parent_region_fixture.default_db_entities() Key = SacogDbEntityKey # The Behavior keyspace behavior_key = BehaviorKey.Fab.ricate # Used to load Behaviors defined elsewhere get_behavior = lambda key: Behavior.objects.get(key=behavior_key(key)) if self.config_entity.key == 'sacog': # Block the client-level region. We just want real regions return [] remote_db_entity_setups = FixtureList( map( lambda db_entity: update_or_create_db_entity( config_entity, db_entity), self.default_remote_db_entities())) # TODO: Disabled the 'sacog_background' 'remote db entity' b/c it is throwing errors (2016-07-06) # return default_db_entities + remote_db_entity_setups + FixtureList([ return default_db_entities + FixtureList([ update_or_create_db_entity( config_entity, DbEntity( key=DbEntityKey.REGION_PRIMARY_GEOGRAPHY, # Override. If a name override is supplied, put it in. Otherwise leave null to derive it from the key name='Urban Base Canvas (UF)', # name=get_property_path(kwargs, 'overrides.%s.name' % Key.BASE), feature_class_configuration=FeatureClassConfiguration( abstract_class=CanvasFeature, # The Base Feature is normally considered a primary_geography unless overridden primary_geography=True, primary_key='geography_id', primary_key_type='int', # The Base Feature is normally associated to a subclass of Geography unless overridden geography_class_name=get_property_path( kwargs, 'overrides.%s.geography_class_name' % Key.BASE_CANVAS) or 'footprint.main.models.geographies.parcel.Parcel', # Create a built_form ForeignKey to a single BuiltForm, # by initially joining our 'built_form_key' attribute to its 'key' attribute related_fields=dict(built_form=dict( single=True, related_class_name=uf_model( 'built_form.built_form.BuiltForm'), source_class_join_field_name='built_form_key', related_class_join_field_name='key', ))), feature_behavior=FeatureBehavior( behavior=get_behavior('base_feature'), ), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.CENSUS_TRACTS, feature_class_configuration=FeatureClassConfiguration( abstract_class=CensusTract), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.CENSUS_BLOCKGROUPS, feature_class_configuration=FeatureClassConfiguration( abstract_class=CensusBlockgroup), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.CENSUS_BLOCK, feature_class_configuration=FeatureClassConfiguration( abstract_class=CensusBlock), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.LIGHT_RAIL, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogLightRailFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity(key=Key.LIGHT_RAIL_STOPS, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogLightRailStopsFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.LIGHT_RAIL_STOPS_ONE_MILE, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogLightRailStopsOneMileFeature, ), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection.polygon_to_polygon ), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.LIGHT_RAIL_STOPS_HALF_MILE, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogLightRailStopsHalfMileFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection.polygon_to_polygon ), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.LIGHT_RAIL_STOPS_QUARTER_MILE, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogLightRailStopsQuarterMileFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection.polygon_to_polygon ), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.VERNAL_POOL, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogVernalPoolFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('environmental_constraint')), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.WETLAND, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogWetlandFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('environmental_constraint')), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( config_entity, DbEntity( key=Key.STREAM, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogStreamFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('environmental_constraint')), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), ])
def default_db_entities(self): """ Scenarios define DbEntities specific to the Scenario. Creates a list a dictionary of configuration functionality. These are filtered based on whether the given scenario matches the scope in the configuration :return: """ scenario = self.config_entity project = self.config_entity.parent_config_entity # The Behavior keyspace behavior_key = BehaviorKey.Fab.ricate # Used to load Behaviors defined elsewhere get_behavior = lambda key: Behavior.objects.get(key=behavior_key(key)) return super(SacogScenarioFixture, self).default_db_entities() + map( lambda db_entity_dict: update_or_create_db_entity( scenario, db_entity_dict['value']), FixtureList([ dict( class_scope=FutureScenario, value=DbEntity( key=DbEntityKey.INCREMENT, feature_class_configuration=FeatureClassConfiguration( abstract_class=CoreIncrementFeature, import_from_db_entity_key=DbEntityKey.BASE_CANVAS, import_ids_only=True, related_fields=dict(built_form=dict( single=True, related_class_name=uf_model( 'built_form.built_form.BuiltForm')))), feature_behavior=FeatureBehavior( behavior=get_behavior('scenario_increment'), intersection=AttributeIntersection( from_attribute='id', to_attribute='id')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.FUTURE_SCENARIO) ]), ), dict( class_scope=FutureScenario, value=DbEntity( key=DbEntityKey.END_STATE, feature_class_configuration=FeatureClassConfiguration( abstract_class=CanvasFeature, import_from_db_entity_key=DbEntityKey.BASE_CANVAS, related_fields=dict(built_form=dict( single=True, related_class_name=uf_model( 'built_form.built_form.BuiltForm')))), feature_behavior=FeatureBehavior( behavior=get_behavior('scenario_end_state'), intersection=AttributeIntersection( from_attribute='id', to_attribute='id')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.FUTURE_SCENARIO) ]), ), dict(class_scope=FutureScenario, value=DbEntity( key=DbEntityKey.FUTURE_AGRICULTURE_CANVAS, name='Scenario Agriculture End State', feature_class_configuration=FeatureClassConfiguration( abstract_class=AgricultureFeature, import_from_db_entity_key=DbEntityKey. BASE_AGRICULTURE_CANVAS, import_ids_only=False, related_fields=dict(built_form=dict( single=True, related_class_name=uf_model( 'built_form.built_form.BuiltForm'), related_class_join_field_name='key', source_class_join_field_name='built_form_key') )), feature_behavior=FeatureBehavior( behavior=get_behavior('agriculture_scenario'), intersection=AttributeIntersection( from_attribute='id', to_attribute='id')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.FUTURE_SCENARIO) ])), dict(class_scope=FutureScenario, value=DbEntity( key=DbEntityKey.FISCAL, feature_class_configuration=FeatureClassConfiguration( abstract_class=FiscalFeature, import_from_db_entity_key=DbEntityKey.BASE_CANVAS, empty_table=True), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=AttributeIntersection( from_attribute='id', to_attribute='id')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.ANALYSIS_RESULTS) ])), dict(class_scope=Scenario, value=DbEntity( key=DbEntityKey.VMT_VARIABLES, feature_class_configuration=FeatureClassConfiguration( abstract_class=VmtVariablesFeature, import_from_db_entity_key=DbEntityKey.BASE_CANVAS, import_ids_only=True, filter_query=dict(), ), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=AttributeIntersection( from_attribute='id', to_attribute='id')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), dict(class_scope=Scenario, value=DbEntity( key=DbEntityKey.VMT, name='Vehicle Miles Traveled Output', feature_class_configuration=FeatureClassConfiguration( abstract_class=VmtFeature, import_from_db_entity_key=DbEntityKey.BASE_CANVAS, empty_table=True), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=AttributeIntersection( from_attribute='id', to_attribute='id')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.ANALYSIS_RESULTS) ])), dict(class_scope=Scenario, value=DbEntity( key=DbEntityKey.ENERGY, name='Energy Demand Output', feature_class_configuration=FeatureClassConfiguration( abstract_class=EnergyFeature, import_from_db_entity_key=DbEntityKey.BASE_CANVAS, empty_table=True), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=AttributeIntersection( from_attribute='id', to_attribute='id')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.ANALYSIS_RESULTS) ])), dict(class_scope=Scenario, value=DbEntity( key=DbEntityKey.WATER, name='Water Demand Output', feature_class_configuration=FeatureClassConfiguration( abstract_class=WaterFeature, import_from_db_entity_key=DbEntityKey.BASE_CANVAS, empty_table=True), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=AttributeIntersection( from_attribute='id', to_attribute='id')), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.ANALYSIS_RESULTS) ])), dict(class_scope=Scenario, value=DbEntity( key=DbEntityKey.PH_VARIABLES, feature_class_configuration=FeatureClassConfiguration( abstract_class=PhVariablesFeature, import_from_db_entity_key=DbEntityKey.GRID_150M, import_ids_only=True, filter_query=dict(), ), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), dict(class_scope=Scenario, value=DbEntity( key=DbEntityKey.PH_GRID_OUTCOMES, feature_class_configuration=FeatureClassConfiguration( abstract_class=PhGridOutcomesFeature, import_from_db_entity_key=DbEntityKey.GRID_150M, import_ids_only=True, filter_query=dict(), ), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), dict(class_scope=Scenario, value=DbEntity( key=DbEntityKey.PH_BLOCK_GROUP_OUTCOMES, name='Public Health Output', feature_class_configuration=FeatureClassConfiguration( abstract_class=PhBlockGroupOutcomesFeature, import_from_db_entity_key=DbEntityKey.GRID_150M, import_ids_only=True, filter_query=dict(), ), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.ANALYSIS_RESULTS) ])), dict(class_scope=Scenario, value=DbEntity( key=DbEntityKey.PH_OUTCOMES_SUMMARY, feature_class_configuration=FeatureClassConfiguration( abstract_class=PhOutcomesSummary, no_table_associations=True, empty_table=True, ), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.ANALYSIS_RESULTS) ])) ]).matching_scope(class_scope=self.config_entity and self.config_entity.__class__))
def feature_class_configuration_as_dict(self, value): self.feature_class_configuration = FeatureClassConfiguration( **value) if isinstance(value, dict) else value
def default_db_entities(self, **kwargs): """ Project specific SACOG additional db_entities :param default_dict: :return: """ project = self.config_entity # The DbEntity keyspace. These keys have no prefix Key = SacogDbEntityKey # The Behavior keyspace behavior_key = BehaviorKey.Fab.ricate # Used to load Behaviors defined elsewhere get_behavior = lambda key: Behavior.objects.get(key=behavior_key(key)) return super(SacogProjectFixture, self).default_db_entities() + [ update_or_create_db_entity( project, DbEntity( key=DbEntityKey.BASE_CANVAS, # Override. If a name override is supplied, put it in. Otherwise leave null to derive it from the key name='UF Urban Base Canvas', # name=get_property_path(kwargs, 'overrides.%s.name' % Key.BASE), feature_class_configuration=FeatureClassConfiguration( abstract_class=CanvasFeature, # The Base Feature is normally considered a primary_geography unless overridden primary_geography=get_property_path( kwargs, 'overrides.%s.primary_geography' % Key.BASE_CANVAS) or True, primary_key='geography_id', primary_key_type='int', # The Base Feature is normally associated to a subclass of Geography unless overridden geography_class_name=get_property_path( kwargs, 'overrides.%s.geography_class_name' % Key.BASE_CANVAS) or 'footprint.main.models.geographies.parcel.Parcel', # Create a built_form ForeignKey to a single BuiltForm, # by initially joining our 'built_form_key' attribute to its 'key' attribute related_fields=dict(built_form=dict( single=True, related_class_name=uf_model( 'built_form.built_form.BuiltForm'), source_class_join_field_name='built_form_key', related_class_join_field_name='key', ))), feature_behavior=FeatureBehavior( behavior=get_behavior('base_feature'), ), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity( key=Key.EXISTING_LAND_USE_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=SacogExistingLandUseParcelFeature, primary_key='geography_id', primary_key_type='int', fields=dict(), related_fields=dict(land_use_definition=dict( single=True, related_class_name= 'footprint.client.configuration.sacog.built_form.sacog_land_use_definition.SacogLandUseDefinition', resource_model_class_name= 'footprint.main.models.built_form.ClientLandUseDefinition', related_class_join_field_name='land_use', source_class_join_field_name='land_use'))), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=AttributeIntersection(from_attribute='id', to_attribute='id')), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity( key=DbEntityKey.BASE_AGRICULTURE_CANVAS, name='UF Agriculture Base Canvas (RUCS)', feature_class_configuration=FeatureClassConfiguration( abstract_class=AgricultureFeature, primary_key='geography_id', primary_key_type='varchar', # Create a built_form ForeignKey to a single BuiltForm, # by initially joining our 'built_form_key' attribute to its 'key' attribute related_fields=dict(built_form=dict( single=True, related_class_name= 'footprint.main.models.built_form.built_form.BuiltForm', related_class_join_field_name='key', source_class_join_field_name='built_form_key'))), feature_behavior=FeatureBehavior( behavior=get_behavior('base_agriculture'), intersection=AttributeIntersection( join_type='attribute')), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity(key=Key.ELK_GROVE_LAND_USE_PARCELS, feature_class_configuration=FeatureClassConfiguration( abstract_class=ElkGroveLandUseParcel), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. centroid_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity(key=Key.CENSUS_RATES, feature_class_configuration=FeatureClassConfiguration( abstract_class=CensusRatesFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('reference'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity(key=Key.GRID_150M, feature_class_configuration=FeatureClassConfiguration( abstract_class=PhGridFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity( key=DbEntityKey.CLIMATE_ZONES, feature_class_configuration=FeatureClassConfiguration( abstract_class=ClimateZoneFeature, related_fields=dict( evapotranspiration_zone=dict( single=True, related_class_name=uf_model( 'policy.water.evapotranspiration_baseline.EvapotranspirationBaseline' ), related_class_join_field_name='zone', source_class_join_field_name= 'evapotranspiration_zone_id'), forecasting_climate_zone=dict( single=True, related_class_name=uf_model( 'policy.energy.commercial_energy_baseline.CommercialEnergyBaseline' ), related_class_join_field_name='zone', source_class_join_field_name= 'forecasting_climate_zone_id'), title_24_zone=dict( single=True, related_class_name=uf_model( 'policy.energy.residential_energy_baseline.ResidentialEnergyBaseline' ), related_class_join_field_name='zone', source_class_join_field_name='title_24_zone_id' ))), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection.polygon_to_centroid ), _categories=[ Category(key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity(key=DbEntityKey.VMT_FUTURE_TRIP_LENGTHS, feature_class_configuration=FeatureClassConfiguration( abstract_class=VmtTripLengthsFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity(key=DbEntityKey.VMT_BASE_TRIP_LENGTHS, feature_class_configuration=FeatureClassConfiguration( abstract_class=VmtTripLengthsFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_centroid), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity(key=Key.BASE_TRANSIT_STOPS, name='GTFS Transit Stops: 2014', feature_class_configuration=FeatureClassConfiguration( abstract_class=TransitStopFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), update_or_create_db_entity( project, DbEntity(key=Key.FUTURE_TRANSIT_STOPS, name='GTFS and Future Transit Stops: 2040', feature_class_configuration=FeatureClassConfiguration( abstract_class=TransitStopFeature), feature_behavior=FeatureBehavior( behavior=get_behavior('internal_analysis'), intersection=GeographicIntersection. polygon_to_polygon), _categories=[ Category( key=DbEntityCategoryKey.KEY_CLASSIFICATION, value=DbEntityCategoryKey.REFERENCE) ])), ]
def clone_or_update_db_entity_and_interest(config_entity, source_db_entity, db_entity, existing_db_entity_interest=None, override_on_update=False): """ Clones or updates the source_db_entity modified with the given kwargs (including possibly the key) into this ConfigEntity. This is used for a duplicate clone from one ConfigEntity (same DbEntity key) to another and also for creating a modified DbEntity for a Result from a non-Result DbEntity (different DbEntity key). A third case for this method is cloning a DbEntity within a ConfigEntity, which is not yet implemented. If the kwargs['override_on_update'] is True, the kwargs should override the target DbEntity attribute values on update. This is useful for the Result clone case where we want to pick up updates to the source DbEntity. But in the straight clone case we want to make the target DbEntity independent of the source once it is created. Returns the DbEntityInterest :param: config_entity. The config_entity of the DbEntities :param: Optional source_db_entity. The source of the clone :param: db_entity. DbEntity of attributes matching the DbEntity that need to override those of the source_db_entity. This might be the key, schema, etc. Also for db_entity.feature_class_owner, default None, is passed in for Results that are copying a reference DbEntity's feature_class_configuration with the db_entity key of the onwer. We don't want the result version of the feature_class_configuration to be used to create the feature_class tables, because that would make foreign key references point to the wrong feature class parents (which are named by the DbEntity id). phwewww! :param: existing_db_entity_interest: Optional DbEntityInterest if it already exists for the clone :param: override_on_update: Default False, optional and is described above. """ # Do a forced adoption of DbEntityInterests from the parent ConfigEntity. This makes sure that ConfigEntity has # the parent's DbEntityInterests before adding any of its own. Otherwise the parent's are never adopted and # are created from the db_entity_configurations instead, which is minimally less efficient # See _adopt_from_donor docs for an explanation. config_entity._adopt_from_donor('db_entities', True) # TODO Update to newer cleaner configuration style # key is always resolved by the db_entity or else the source DbEntity key key = db_entity.key or source_db_entity.key feature_behavior = db_entity._feature_behavior if existing_db_entity_interest: # Merge existing DbEntity data, including the id. Manually merge feature_behavior since it's not a real # property db_entity.__dict__.update( merge( model_dict(existing_db_entity_interest.db_entity, include_primary_key=True), dict(_feature_behavior=existing_db_entity_interest.db_entity. feature_behavior))) if not db_entity._feature_behavior: from footprint.main.publishing.config_entity_initialization import get_behavior # If we don't already have a feature_behavior get it from the source DbEntity but 0 the id to make a copy # We'll also 0 out the Intersection of the FeatureBehavior and pass it to the FeatureBehavior creator # If we don't have a source_db_entity then create a default FeatureBehavior feature_behavior = source_db_entity.feature_behavior if \ source_db_entity else \ FeatureBehavior( behavior=get_behavior('reference') ) feature_behavior.id = None # Prefer the db_entity values over those of the source_db_entity db_entity.__dict__.update(merge( # Start with the source attributes model_dict(source_db_entity) if source_db_entity else {}, # Copy the feature_behavior by assigning it to the temp property _feature_behavior # Prefer the FeatureBehavior of the new DbEntity (for the Result case) dict(_feature_behavior=feature_behavior), # Override with the initial clone overrides or existing clone values. model_dict(db_entity), # If update_on_override then overwrite the clone with the source values # This is for the case of updating the source configuration and wanting to mirror changes to the Result DbEntities remove_keys(model_dict(source_db_entity), ['key', 'schema', 'name']) if source_db_entity and override_on_update else {}, # Set the clone source key if different than the target key dict(source_db_entity_key=source_db_entity.key) if source_db_entity and source_db_entity.key != key else {}, dict( # Override feature_class_configuration keys if specified in the kwargs and create_or_update_on_override is True feature_class_configuration=FeatureClassConfiguration(**merge( # start with the source's attributes source_db_entity.feature_class_configuration.__dict__ if source_db_entity else {}, # override with all those present on the clone if create_or_update_on_override is false, if true add only those unspecified on the source # The only exception is abstract_class_name, which must always come from the source remove_keys(db_entity.feature_class_configuration.__dict__, source_db_entity.feature_class_configuration.__dict__.keys() if \ source_db_entity and override_on_update else \ ['abstract_class_name'] ), # feature_class_owner is set to the owning db_entity key for a Result DbEntity creation so that # the result feature_class_configuration doesn't create feature classes/tables # We either copy this value from the source feature_class_configuration (clone case) or get it from the kwargs (create Result DbEntity case) dict( feature_class_owner=source_db_entity.feature_class_configuration.feature_class_owner if \ source_db_entity else \ db_entity.feature_class_configuration.feature_class_owner, ) )) ) )) # There must be a creator of a new DbEntity. The updater is that of the source DbEntity or simply the creator try: db_entity.creator = db_entity.creator except: db_entity.creator = source_db_entity.creator logger.debug(db_entity.creator.__class__) try: db_entity.updater = db_entity.updater except: db_entity.updater = db_entity.creator # Persist the feature_behavior FeatureBehavior._no_post_save_publishing = True db_entity.update_or_create_feature_behavior(db_entity._feature_behavior) # # save to persist the db_entity's knowledge of its behavior # db_entity.save() FeatureBehavior._no_post_save_publishing = False # This will trigger DbEntity post-save publishing, but the only thing that actually # runs is UserPublishing in order to give users permission to the DbEntity # The other publishers detect that the DbEntity has a source_db_entity_key and quit db_entity_interest = update_or_create_db_entity_and_interest( config_entity, db_entity)[0] # Copy the categories from the source if it exists if source_db_entity: db_entity_interest.db_entity.categories.add( *source_db_entity.categories.all()) return db_entity_interest
def crud_db_entities(config_entity, crud, db_entity_keys=None): """ Creates or updates the db_entities of the ConfigEntity :param config_entity :param crud CrudKey.CREATE, CrudType.CLONE, CrudType.UPDATE, CrudType.SYNC, CrudType.DELETE (unimplemented) :return: """ from footprint.client.configuration.fixture import ConfigEntityFixture # If not present, create the database schema for this ConfigEntity's feature table data PGNamespace.objects.create_schema(config_entity.schema()) client_fixture = ConfigEntityFixture.resolve_config_entity_fixture( config_entity) db_entity_filter = dict(key__in=db_entity_keys) if db_entity_keys else {} # Process the DbEntities from the origin_instance or the db_entity_configuration from the fixtures, # but only the first time this scenario is saved # We only get those scoped (owned) by the class of our config_entity. The scoped above will be adopted automatically # and need not be created. This means a Scenario creates DbEntities scoped to Scenario and adopts those scoped # to Project or Region. It does not clone the latter. if CrudKey.CLONE == crud: # CRUD the DbEntities to match the origin instance origin_instance = config_entity.origin_instance # Clone the DbEntities from the origin ConfigEntity. db_entities = map( lambda source_db_entity: clone_or_update_db_entity_and_interest( config_entity, source_db_entity, DbEntity(schema=config_entity.schema(), feature_class_configuration=FeatureClassConfiguration( geography_scope=FeatureClassCreator( config_entity).resolved_geography_scope.id, class_attrs={ 'config_entity__id': config_entity.id, 'override_db': config_entity.db, 'db_entity_key': source_db_entity.key }))).db_entity, origin_instance.owned_db_entities(**db_entity_filter)) elif crud in [CrudKey.SYNC, CrudKey.CREATE]: #TODO examine the two conditions below more carefully. We want syncing to be the same for clones and non-clones if config_entity.origin_instance: # Syncing previously cloned instance db_entities = config_entity.owned_db_entities(**db_entity_filter) update_or_create_db_entities_and_interests(config_entity, *db_entities) else: # Create or Sync new instance # Get the default DbEntity configurations from the fixture default_db_entities = filter( lambda db_entity: db_entity.key in db_entity_keys if db_entity_keys else True, client_fixture.default_db_entities()) # Find additional owned (not adopted) db_entities that aren't defaults, namely those that were created by the user additional_db_entities = filter( lambda db_entity: db_entity.key in db_entity_keys if db_entity_keys else True, client_fixture.non_default_owned_db_entities()) # Combine the defaults with the additions db_entities = default_db_entities + list(additional_db_entities) update_or_create_db_entities_and_interests(config_entity, *db_entities) elif CrudKey.UPDATE == crud: # No complex updates are enabled for scenarios, so no post-save processing is needed return elif CrudKey.DELETE == crud: raise NotImplementedError("DELETE is not implemented") # Disable the post_post_save signal while saving to prevent an infinite loop previous = config_entity._no_post_save_publishing config_entity._no_post_save_publishing = True # Save post_create changes. This is just to store selected DbEntities config_entity.save() config_entity._no_post_save_publishing = previous reset_queries()
def on_db_entity_interest_post_save(sender, **kwargs): """ Called after a DbEntityInterest saves, but not when a config_entity is running post_save publishers In other words, this is only called after a direct DbEntityInterest save/update. This does the same as post_save_config_entity, but starts with the 'post_save_config_entity_db_entities' signal to do only DbEntity dependent presentation. """ db_entity_interest = kwargs['instance'] config_entity = ConfigEntity._subclassed(db_entity_interest.config_entity) db_entity = db_entity_interest.db_entity # TODO The default user should be the admin user = db_entity.updater if db_entity.updater else get_user_model( ).objects.get(username=UserGroupKey.SUPERADMIN) # post_save_db_entity presentation should always be disabled if we are saving a ConfigEntity logger.info( "Handler: post_save_db_entity_interest for config_entity {config_entity}, db_entity {db_entity}, " "and user {username}.".format(config_entity=config_entity, db_entity=db_entity_interest.db_entity, username=user.username)) if kwargs.get('created', None): db_entity = db_entity_interest.db_entity # TODO # While we test upload, just delete the previous DbEntitys with the same key name # in the ConfigEntity. db_entity_interest.config_entity.db_entities.filter( key=db_entity.key).exclude(id=db_entity.id).delete() # Make sure the db_entity's schema matches the config_entity's if not set # TODO we assume that the schema should match the config_entity, rather than # an ancestor or the config_entity (like the project or a scenario). There # are many cases where the schema should not be that of the config_entity, so # we might want to remove this default and force the saver to set it if not db_entity.schema or not db_entity.table: db_entity.schema = db_entity.schema or db_entity_interest.config_entity.schema( ) # Always base the table name on the key db_entity.table = db_entity.key db_entity_interest.db_entity.save() if db_entity_interest.config_entity.deleted: # Do nothing for deleted config_entities return # Define the data_importer if not already set if not (db_entity.feature_class_configuration and db_entity.feature_class_configuration.data_importer): feature_class_configuration = db_entity.feature_class_configuration = db_entity.feature_class_configuration or FeatureClassConfiguration( ) # Choose the correct importer, if any, to set up the feature_class_configuration and features if db_entity.origin_instance: # Import from the origin_instance. This could be a full copy or from the current layer selection features feature_class_configuration.data_importer = full_module_path( OriginDbEntityProcessor) elif '.json' in db_entity.url.lower(): # Import it using the geojson importer feature_class_configuration.data_importer = full_module_path( GeoJsonProcessor) # Indicate that the feature class configuration was generated not fixture based feature_class_configuration.generated = True elif '.zip' in db_entity.url.lower(): feature_class_configuration.data_importer = full_module_path( ZippedSqlFileProcessor) # Indicate that the feature class configuration was generated not fixture based feature_class_configuration.generated = True elif not db_entity.no_feature_class_configuration: feature_class_configuration.data_importer = full_module_path( DefaultImportProcessor) previous = DbEntityInterest._no_post_save_publishing DbEntityInterest._no_post_save_publishing = True db_entity.feature_class_configuration = feature_class_configuration db_entity.save() DbEntityInterest._no_post_save_publishing = previous # Post save presentation section # Quit if the publishers were turned off outside this method if DbEntityInterest._no_post_save_publishing or db_entity_interest._no_post_save_publishing: return # Use this to initialize the FeatureBehavior and other stuff that might not be set update_or_create_db_entity(config_entity, db_entity) starting_signal_path = resolvable_module_attr_path( __name__, 'post_save_db_entity_initial') return post_save_publishing( starting_signal_path, config_entity, user, instance=db_entity_interest, instance_class=DbEntity, client_instance_path='db_entity', instance_key=db_entity_interest.db_entity.key, signal_proportion_lookup=signal_proportion_lookup, dependent_signal_paths=dependent_signal_paths, signal_prefix='post_save_db_entity', # Update the setup_percent_complete instance attribute for new instances # of classes with this attribute (currently only DbEntity) update_setup_percent_complete=db_entity_interest.db_entity. setup_percent_complete == 0, **filter_keys(kwargs, ['created']))