Skip to main content
`Ctrl`+`K`

# ng911ok.lib.gdbsession module

class DummyEditor(session: NG911Session | None = None)

  Bases: `object`

  Class to be instantiated as the value of `NG911Session.editor` for instances of that class not using an edit session. This will prevent method calls from failing as opposed to simply setting that attribute to `None`.

  abortOperation()
  redoOperation()
  startEditing(with_undo=True, multiuser_mode=True)
  startOperation()
  stopEditing(save_changes=True)
  stopOperation()
  undoOperation()
  property isEditing
  property workspacePath

class FallbackGPMessenger(*args, **kwargs)

  Bases: `GPMessenger`

  Provides fallback functionality when no geoprocessing messenger is available.

  addErrorMessage(message: str) → None
  addGPMessages() → None
  addIDMessage(message_type: Literal['ERROR', 'INFORMATIVE', 'WARNING'], message_ID: int, add_argument1: str | int | float | None = None, add_argument2: str | int | float | None = None) → None
  addMessage(message: str) → None
  addWarningMessage(message: str) → None
  _abc_impl = <_abc._abc_data object>
  _is_protocol = False

class GPMessenger(*args, **kwargs)

  Bases: `Protocol`

  Protocol declaring the methods of the `messages` parameter of geoprocessing tool class `execute` methods.

  abstractmethod addErrorMessage(message: str) → None
  abstractmethod addGPMessages() → None
  abstractmethod addIDMessage(message_type: Literal['ERROR', 'INFORMATIVE', 'WARNING'], message_ID: int, add_argument1: str | int | float | None = None, add_argument2: str | int | float | None = None) → None
  abstractmethod addMessage(message: str) → None
  abstractmethod addWarningMessage(message: str) → None
  _abc_impl = <_abc._abc_data object>
  _is_protocol = True
  _is_runtime_protocol = True

class NG911Session(workspace: PathLike[str] | str, respect_submit: bool, use_edit_session: bool = False, messenger: GPMessenger | None = None, **env_kwargs)

  Bases: `EnvManager`, `PathLike`[`str`]

  classmethod create_standard_gdb(output_directory: Path | str, name: str, spatial_reference: SpatialReference, messenger: GPMessenger | None = None) → Self
  _add_optional_ds_topology(replace: bool = False) → bool

    If `topology_config` specifies at least one rule and at least one member for a topology in the optional feature dataset, this method creates a topology for that dataset if one does not already exist. It does not add any rules or members to the new topology.

    The new topology will have the name specified by `topology_config.optional_dataset_topology_name`.

    Parameters:

      replace (bool) – Whether to delete and recreate the topology if one already exists. Has no effect if one does not already exist or if `topology_config` specifies no rules or no members for the new topology. Default False.

    Returns:

      Whether a new topology was created

    Return type:

      bool

  _add_required_ds_topology(replace: bool = False) → bool

    If `topology_config` specifies at least one rule and at least one member for a topology in the required feature dataset, this method creates a topology for that dataset if one does not already exist. It does not add any rules or members to the new topology.

    The new topology will have the name specified by `topology_config.required_dataset_topology_name`.

    Parameters:

      replace (bool) – Whether to delete and recreate the topology if one already exists. Has no effect if one does not already exist or if `topology_config` specifies no rules or no members for the new topology. Default False.

    Returns:

      Whether a new topology was created

    Return type:

      bool

  _add_standard_domains() → int

    Attempts to add all domains prescribed by the Standard and set their split policies to `DUPLICATE`. Returns the number of domains successfully added and configured.

    This method is intended to be called by `create_standard_gdb()`.

  _add_standard_feature_datasets(spatial_reference: SpatialReference, required: bool = True, optional: bool = True) → tuple[bool, bool]

    Creates the required feature dataset and/or the optional feature dataset in the geodatabase. Returns a `tuple` of `bool`s indicating whether the required and optional datasets, respectively, were created.

    This method is intended to be called by `create_standard_gdb()`.

  _configure_topology(ds_env_manager: EnvManager, topology_name: str, rules: Sequence[TopologyRule]) → tuple[int, int] | None

    Given an `arcpy.EnvManager`, topology name, and sequence of rules, adds those rules and their members to the topology topology_name.

    Note

    Parameter ds_env_manager is intended to be set to either `required_ds_env_manager` or `optional_ds_env_manager`.

    Parameters:

      - ds_env_manager (arcpy.EnvManager) – An environment manager with the workspace set to the target feature dataset

      - topology_name (str) – Name of the topology to configure

      - rules (Sequence[TopologyRule]) – Rules to add to the topology

    Returns:

      Tuple of numbers of rules and feature classes, respectively, added to the topology; `(0, 0)` if there is no topology

    Return type:

      tuple[int, int]

  _copy_to_zip(destination: Path | str, overwrite: bool = False, *, staged_gdb_path: Path | None = None) → Path

    Creates a .zip file with the contents of the geodatabase. Files with a name ending in “.lock” are excluded.

    Warning

    Unline `export_to_zip()`, this method does NOT respect the SUBMIT attribute!

    Parameters:

      - destination (pathlib.Path) – Path to zip file to be created; must end in “.gdb.zip”

      - overwrite (bool) – Whether to overwrite any existing file at `destination`, default False

      - staged_gdb_path (Optional[pathlib.Path]) – If given, uses this argument as the path to the geodatabase to export instead of `self.gdb_path`, default None

    Returns:

      Absolute path to the output file

    Return type:

      pathlib.Path

  _delete_temporary_item(item: str) → bool
  _delete_temporary_items() → int
  _temp_fc_name(base_name: str) → str

    Creates and keeps track of a unique name for a temporary feature class to be stored in memory. The feature class is deleted when the context manager exits.

  _temp_layer_name(base_name: str) → str

    Creates and keeps track of a unique name for a temporary feature layer. The layer is deleted when the context manager exits.

  add_and_configure_topologies(replace: bool = False) → tuple[bool, bool]

    Adds topologies and their respective rules and members to the required and optional feature datasets.

    Parameters:

      replace (bool) – Whether to delete and recreate each topology that already exists. Has no effect for one does not already exist or if `topology_config` specifies no rules or no members for that topology. Default False.

    Returns:

      Whether the required and optional topologies, respectively, were modified

    Return type:

      tuple[bool, bool]

  append_to_feature_class(feature_class: NG911FeatureClass, source: Path, source_to_standard_mapping: dict[str, str] | None = None) → int

    Appends rows from source to the standard feature class feature_class. An optional field mapping dictionary may be provided with source field names as keys and standard field `NG911Field.name` (not `NG911Field.role`) as values.

    Parameters:

      - feature_class – The feature class to append to

      - source – NG911FeatureClass

      - source_to_standard_mapping

    Returns:

  assign_nguids(feature_class: NG911FeatureClass, assign_method: Literal[NGUIDAssignMethod.NGUID], nguid_field_name: str | None = None, agency_id_field_name: str | None = None, local_id_field_name: str | None = None, feature_class_name: str | None = None, *, convert_format: bool = False, overwrite: bool = False, update_local_id_field: bool = True) → int
  assign_nguids(feature_class: NG911FeatureClass, assign_method: Literal[NGUIDAssignMethod.NGUID], *, convert_format: bool = False, overwrite: bool = False, update_local_id_field: bool = True) → int
  assign_nguids(feature_class: NG911FeatureClass, assign_method: Literal[NGUIDAssignMethod.LOCAL], nguid_field_name: str | None = None, agency_id_field_name: str | None = None, local_id_field_name: str | None = None, feature_class_name: str | None = None, *, overwrite: bool = False) → int
  assign_nguids(feature_class: NG911FeatureClass, assign_method: Literal[NGUIDAssignMethod.LOCAL], *, overwrite: bool = False) → int
  assign_nguids(feature_class: NG911FeatureClass, assign_method: Literal[NGUIDAssignMethod.SEQUENTIAL], nguid_field_name: str | None = None, agency_id_field_name: str | None = None, local_id_field_name: str | None = None, feature_class_name: str | None = None, *, overwrite: bool = False, update_local_id_field: bool = True) → int
  assign_nguids(feature_class: NG911FeatureClass, assign_method: Literal[NGUIDAssignMethod.SEQUENTIAL], *, overwrite: bool = False, update_local_id_field: bool = True) → int

    Assigns new NGUIDs to feature_class (or, if supplied, feature_class_name) in this geodatabase using assign_method. If assign_method is `NGUID`, this method can optionally convert existing NGUIDs from the format used in Standards v2.2 to the format used in Standards v3.

    Valid arguments for assign_method are:

    - `NGUID`: Updates (and optionally converts) existing NGUID, changing the agency ID if the value of that field is inconsistent with the existing NGUID

    - `LOCAL`: Computes NGUID based on the Local_ID field

    - `SEQUENTIAL`: Computes NGUID based on a counter, starting from 1

    Parameters:

      - feature_class – NG911 standard feature class for which NGUIDs will be computed

      - assign_method – Method to use to compute new NGUIDs

      - nguid_field_name – Name of the NGUID field; should only be provided if feature_class is nonstandard; default None

      - agency_id_field_name – Name of the agency ID field; should only be provided if feature_class is nonstandard; default None

      - local_id_field_name – Name of the Local_ID field; should only be provided if feature_class is nonstandard; default None

      - feature_class_name – Name of the target feature class in this geodatabase if the name is nonstandard; default None

      - convert_format – Whether to convert existing NGUIDs from the format used in Standards v2.2 to that used in v3; only allowed if assign_method is `NAM.NGUID`; default False

      - overwrite – If True, compute and overwrite NGUIDs for all features; if False, compute and set NGUIDs only for features where the NGUID attribute is null or a blank string; default False

      - update_local_id_field – Whether update the local ID field if it would otherwise be out of sync with the NGUID; ignored for assign_method `LOCAL`; default True

    Returns:

      Number of features with new NGUIDs assigned

  count(feature_class: NG911FeatureClass, where_clause: str | None = None) → int

    Counts the number of features in a feature class using OGR, with an optional where clause. This is much faster than using ArcPy or Pandas.

  create_standard_feature_class(feature_class: NG911FeatureClass, overwrite: bool = False) → Path

    Creates a standard feature class based on the specifications in `config.yml`.

    Parameters:

      - feature_class (NG911FeatureClass) – The feature class to create

      - overwrite – Whether to overwrite an existing feature class, if present; default False

    Returns:

      Path to the newly-created feature class

    Return type:

      pathlib.Path

  export_to_zip(destination: Path | str, respect_submit: bool | None = None, overwrite: bool = False, add_topology: bool = True) → Path

    Exports NG911 feature classes to a temporary geodatabase, zips it, and returns the absolute path to the zipped geodatabase.

    Note

    Unline `_copy_to_zip()`, this method does respect the SUBMIT attribute!

    Parameters:

      - destination (pathlib.Path) – Path to zip file to be created; must end in “.gdb.zip”

      - respect_submit (Optional[bool]) – Whether to only export features where the SUBMIT attribute is ‘Y’; if not specified, uses `self._respect_submit`

      - overwrite (bool) – Whether to overwrite any existing file at `destination`, default False

      - add_topology (bool) – Whether to add and validate topology rules, default True

    Returns:

      Absolute path to the output file

    Return type:

      pathlib.Path

  import_esn_polygons(source_fc: PathLike[str] | str, field_map: Mapping[NG911Field | str, Field | str | None], assign_sequential_nguids: bool = False, esz_nguid_method: NGUIDAssignMethod = NGUIDAssignMethod.NULL, convert_nguids: bool = False, esb_to_display_name: bool = False, overwrite: bool = False) → tuple[Path | None, Path | None, Path | None, Path | None]

    Given a source feature class with ESN polygons, derives the feature classes `
    ESB_EMS_BOUNDARY`, `
    ESB_FIRE_BOUNDARY`, `
    ESB_LAW_BOUNDARY`, and `
    ESZ_BOUNDARY`

    Parameters:

      - source_fc – Path to ESN polygon feature class

      - field_map – Mapping of standard fields to source fields

      - assign_sequential_nguids – Whether to assign sequential NGUID attributes to the output ESB (but not ESZ) features; default False

      - esz_nguid_method – Method to use to assign NGUIDs to the output ESZ features; default None

      - convert_nguids – Whether to convert existing NGUIDs from the format used in Standards v2.2 to that used in v3; only applies to the output `
        ESZ_BOUNDARY` feature class and only allowed if esz_nguid_method is `NAM.NGUID`; default False

      - esb_to_display_name – Whether to copy ESB attributes (`
        EMS`/`
        FIRE`/`
        LAW`) to the `
        DsplayName` field, default False

      - overwrite – Whether to overwrite existing ESB and ESZ feature classes, default False

    Returns:

      Paths to derived EMS, fire, law enforcement, and ESZ polygon feature classes, respectively (replaced with `None` for feature classes where errors were encountered during processing)

    Return type:

      tuple[Path | None, Path | None, Path | None, Path | None]

  load_df(feature_class: NG911FeatureClass, fields: Sequence[NG911Field | Literal['OID@'] | str] | None = None, respect_submit: bool | None = None, **kwargs) → DataFrame

    Loads and returns a Spatially-Enabled `DataFrame` containing the data of feature_class.

    This method specifically sets the index of the `DataFrame` to the NGUID column, and it does so without dropping the column if the NGUID field is in fields. This provides for compatibility with `validation.FeatureAttributeErrorMessage.from_df()`.

    The resulting `DataFrame`‘s `attrs` dict will be an instance of `_NG911DataFrameAttrs`.

    Note

    The NGUID field will be loaded regardless of whether it was included in fields, but it will only be included as a regular column if it was included in fields.

    See also

    `_NG911DataFrameAttrs`

    Parameters:

      - feature_class (NG911FeatureClass) – The feature class to load

      - fields (Optional[Sequence[NG911Field | Literal["OID@"] | str]]) – The fields to include, as either `NG911Field` objects or field names; the string `OID@` is also allowed and will be replaced with the name of the `OBJECTID` field

      - respect_submit (Optional[bool]) – Whether to only return features where the `
        SUBMIT` attribute is `"Y"`; defaults to `_respect_submit`

      - kwargs (Any) – Additional keyword arguments to pass to `pandas.DataFrame.spatial.from_featureclass()`

    Returns:

      The feature class data in a `pandas.DataFrame`

    Return type:

      pandas.DataFrame

  path_to(item: NG911FeatureClass | str) → Path

    Returns the absolute path to item in the geodatabase, where item is any of the following:

    - An NG911FeatureClass instance

    - A valid NG911FeatureClass role

    - The name of the required or optional feature dataset

    - The name of the required or optional dataset topology

    Parameters:

      item (NG911FeatureClass | str) – The geodatabase item for which a path will be returned

    Returns:

      Path to item

    Return type:

      pathlib.Path

  str_path_to(item: NG911FeatureClass | str) → str

    Returns the absolute path to item in the geodatabase as a `str`. See `path_to()`.

    Parameters:

      item (NG911FeatureClass | str) – The geodatabase item for which a path will be returned

    Returns:

      Path to item as a `str`

    Return type:

      str

  to_shapefiles(destination: Path | str, respect_submit: bool | None = None, overwrite: bool = False) → list[Path]

    Exports all NG911 feature classes to individual shapefiles.

    Parameters:

      - destination (pathlib.Path | str) – Path to the output directory

      - respect_submit (Optional[bool]) – Whether to only export those features where the `SUBMIT` attribute is ‘Y’, defaults to `self._respect_submit`

      - overwrite (bool) – Whether to overwrite files in the output directory if needed, default False

    Returns:

      Paths to the output shapefiles (only the .shp files)

    Return type:

      list[pathlib.Path]

  validate_topologies() → tuple[bool, bool]

    Validates the required and/or optional dataset topologies if each exists.

    Returns:

      Whether the required and optional dataset topologies, respectively, were validated

    Return type:

      tuple[bool, bool]

  _abc_impl = <_abc._abc_data object>
  _enter_timestamp: datetime | None

    Set to `None` at initialization, to the current time when `__enter__()` is called, and back to `None` when `__exit__()` is called. Used in initilizing `ValidationErrorMessage`s.

  _gdb: Path

    Path to the NG911 geodatabase.

  _init_timestamp: datetime

    Set to the current time at initialization.

  _is_active: bool

    Whether the environment settings (including workspace) are in effect.

  _respect_submit: bool

    Whether to use `SUBMIT='Y'` in where clauses by default.

  _temporary_items: list[str]

    Keeps track of temporary feature classes and layers to delete upon `__exit__()` or `__del__()` being called.

  _use_edit_session: bool

    Whether to utilize an `arcpy.da.Editor` instance.

  editor: Workspace Editor | ~ng911ok.lib.gdbsession.DummyEditor

    An instance of `arcpy.da.Editor` for managing edits when `_use_edit_session` is `True`. Otherwise, a `DummyEditor` instance is created, and calling methods on it will have no effect.

  property gdb: str

    This is essentially a shortcut for `arcpy.env.workspace` that also checks to ensure that the `NG911Session` instance is currently active (i.e. is being accessed within the `with` statement or is being accessed between calls to `__enter__()` and `__exit__()`).

    Returns:

      Path to the current workspace

    Return type:

      str

  property gdb_path: Path

    Returns a `pathlib.Path` instance representing the geodatabase directory.

  messenger: SessionMessenger

    The geoprocessing messenger object typically passed to the `execute` method of a geoprocessing tool (or an instance of `FallbackGPMessenger`).

  property optional_ds_env_manager: EnvManager

    Shortcut to get an instance of `arcpy.EnvManager` with the workspace set to the optional feature dataset of the Validator instance’s geodatabase and all other environment settings copied from the Validator instance.

  property optional_ds_exists: bool

    Returns whether the geodatabase contains a feature dataset with the prescribed name of the optional feature dataset.

  property optional_ds_topology_exists: bool

    Returns whether the optional feature dataset contains a topology with the expected name. Does not indicate whether it contains any rules or members.

  property required_ds_env_manager: EnvManager

    Shortcut to get an instance of `arcpy.EnvManager` with the workspace set to the required feature dataset of the Validator instance’s geodatabase and all other environment settings copied from the Validator instance.

  property required_ds_exists: bool

    Returns whether the geodatabase contains a feature dataset with the prescribed name of the required feature dataset.

  property required_ds_topology_exists: bool

    Returns whether the required feature dataset contains a topology with the expected name. Does not indicate whether it contains any rules or members.

  property respect_submit: bool

    Returns whether operations with an instance of this class are to only apply to those features where the `SUBMIT` attribute is equal to `"Y"`.

class NGUIDBuilder(target: ~ng911ok.lib.gdbsession.NG911Session | ~os.PathLike[str] | str, feature_class: ~ng911ok.lib.config_dataclasses.NG911FeatureClass, overwrite: bool = False, nguid_field_name: str = NOTHING, agency_id_field_name: str = NOTHING, convert_format: bool = False, *, messenger: ~ng911ok.lib.gdbsession.GPMessenger = NOTHING, editor: Workspace Editor | ~ng911ok.lib.gdbsession.DummyEditor = NOTHING)

  Bases: `ABC`, `_AttrsInstanceWithAllowedFields`

  Abstract base class for NGUID builder classes. There should be one concrete subclass for each value of `NAM` (except for `COPY` and `NULL`).

  abstractmethod assign() → int

    Assigns NGUID attributes to the target feature class.

    Returns:

      The number of features updated

    Return type:

      int

  _abc_impl = <_abc._abc_data object>
  _is_protocol = False
  _target: NG911Session | PathLike[str] | str
  property _update_cursor: UpdateCursor
  property _where_clause: str

    Returns either a where-clause or `None` based on the builder’s `overwrite` and `nguid_field_name`. The result can be passed to ArcPy functions that take a where-clause.

  agency_id_field_name: str
  assign_method: ClassVar[NAM]
  convert_format: bool
  abstract property cursor_fields: tuple[str, str] | tuple[str, str, str]

    Returns the fields used by the `UpdateCursor`.

  editor: arcpy.da.Editor | DummyEditor
  feature_class: NG911FeatureClass
  messenger: GPMessenger
  nguid_field_name: str
  overwrite: bool
  property parse_nguid: Callable[[str], NGUID]
  property session: NG911Session | None

    Returns the `NG911Session` passed during initialization if one was passed, otherwise returns `None`.

  property target_fc: Path

    Returns the path to the feature class to be updated.

  property target_fc_str: str

    Returns the path to the feature class to be updated as a string.

class NGUIDFromLocalIDBuilder(target: ~ng911ok.lib.gdbsession.NG911Session | ~os.PathLike[str] | str, feature_class: ~ng911ok.lib.config_dataclasses.NG911FeatureClass, overwrite: bool = False, nguid_field_name: str = NOTHING, agency_id_field_name: str = NOTHING, local_id_field_name: str = NOTHING, *, messenger: ~ng911ok.lib.gdbsession.GPMessenger = NOTHING, editor: Workspace Editor | ~ng911ok.lib.gdbsession.DummyEditor = NOTHING)

  Bases: `NGUIDBuilder`

  assign() → int

    Assigns NGUID attributes to the target feature class.

    Returns:

      The number of features updated

    Return type:

      int

  _abc_impl = <_abc._abc_data object>
  _is_protocol = False
  assign_method: ClassVar[NAM] = 'LOCAL'
  convert_format: Literal[False]
  property cursor_fields: tuple[str, str, str]

    Returns the fields used by the `UpdateCursor`.

  local_id_field_name: str

class NGUIDFromNGUIDBuilder(target: ~ng911ok.lib.gdbsession.NG911Session | ~os.PathLike[str] | str, feature_class: ~ng911ok.lib.config_dataclasses.NG911FeatureClass, overwrite: bool = False, nguid_field_name: str = NOTHING, agency_id_field_name: str = NOTHING, convert_format: bool = False, update_local_id_field: bool = True, local_id_field_name: str | None = NOTHING, *, messenger: ~ng911ok.lib.gdbsession.GPMessenger = NOTHING, editor: Workspace Editor | ~ng911ok.lib.gdbsession.DummyEditor = NOTHING)

  Bases: `NGUIDBuilder`

  assign() → int

    Assigns NGUID attributes to the target feature class.

    Returns:

      The number of features updated

    Return type:

      int

  _abc_impl = <_abc._abc_data object>
  _is_protocol = False
  assign_method: ClassVar[NAM] = 'NGUID'
  property cursor_fields: tuple[str, str] | tuple[str, str, str]

    Returns the fields used by the `UpdateCursor`.

  local_id_field_name: str | None
  update_local_id_field: bool

class SequentialNGUIDBuilder(target: ~ng911ok.lib.gdbsession.NG911Session | ~os.PathLike[str] | str, feature_class: ~ng911ok.lib.config_dataclasses.NG911FeatureClass, overwrite: bool = False, nguid_field_name: str = NOTHING, agency_id_field_name: str = NOTHING, update_local_id_field: bool = True, local_id_field_name: str | None = NOTHING, *, messenger: ~ng911ok.lib.gdbsession.GPMessenger = NOTHING, editor: Workspace Editor | ~ng911ok.lib.gdbsession.DummyEditor = NOTHING)

  Bases: `NGUIDBuilder`

  assign() → int

    Assigns NGUID attributes to the target feature class.

    Returns:

      The number of features updated

    Return type:

      int

  _abc_impl = <_abc._abc_data object>
  _is_protocol = False
  assign_method: ClassVar[NAM] = 'SEQUENTIAL'
  convert_format: Literal[False]
  property cursor_fields: tuple[str, str] | tuple[str, str, str]

    Returns the fields used by the `UpdateCursor`.

  local_id_field_name: str | None
  update_local_id_field: bool

class SessionMessenger(tool_messenger: GPMessenger | None = None)

  Bases: `object`

  addErrorMessage(message: str, *, level: int = logging.ERROR) → None
  addErrorMessage(message: str, *, level: int = logging.ERROR, exc: _T_Exc) → _T_Exc
  addGPMessages() → None
  addIDMessage(message_type: Literal['ERROR', 'INFORMATIVE', 'WARNING'], message_ID: int, add_argument1: str | int | float | None = None, add_argument2: str | int | float | None = None) → None
  addMessage(message: str, *, level: int = 20, exc: BaseException | None = None) → None
  addWarningMessage(message: str, *, level: int = 30, exc: BaseException | None = None) → None

class _NG911DataFrameAttrs

  Bases: `TypedDict`

  Represents the keys of the `attrs` attribute of `DataFrame`s returned by `NG911Session.load_df()`.

  feature_class: NG911FeatureClass
  fields: tuple[NG911Field, ...]
  geodatabase_path: Path
  nguid_name: str
  oid_name: str | None
  path: Path
  shape_name: str

_validate_local_id_field_if_needed(instance: NGUIDFromNGUIDBuilder | SequentialNGUIDBuilder, attribute: attrs.Attribute[str | None], value: str | None) → None

  `attrs`-compatible validator intended for use specifically with subclasses of `NGUIDBuilder` that can write to a local ID field. Intended to ensure one of the following:

  - Local ID should not be modified and a local ID field name is not provided

  - Local ID should be modified, a local ID field name is provided, and that field exists