nodes: 0, module; 1, function_definition; 2, function_name:create_db; 3, parameters; 4, block; 5, identifier:data; 6, identifier:dbfn; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, default_parameter; 13, default_parameter; 14, default_parameter; 15, default_parameter; 16, default_parameter; 17, default_parameter; 18, default_parameter; 19, default_parameter; 20, default_parameter; 21, default_parameter; 22, default_parameter; 23, default_parameter; 24, default_parameter; 25, default_parameter; 26, default_parameter; 27, default_parameter; 28, default_parameter; 29, dictionary_splat_pattern; 30, expression_statement; 31, expression_statement; 32, comment:# Check if any older kwargs made it in; 33, expression_statement; 34, expression_statement; 35, comment:# First construct an iterator so that we can identify the file format.; 36, comment:# DataIterator figures out what kind of data was provided (string of lines,; 37, comment:# filename, or iterable of Features) and checks `checklines` lines to; 38, comment:# identify the dialect.; 39, expression_statement; 40, expression_statement; 41, if_statement; 42, comment:# However, a side-effect of this is that  if `data` was a generator, then; 43, comment:# we've just consumed `checklines` items (see; 44, comment:# iterators.BaseIterator.__init__, which calls iterators.peek).; 45, comment:#; 46, comment:# But it also chains those consumed items back onto the beginning, and the; 47, comment:# result is available as as iterator._iter.; 48, comment:#; 49, comment:# That's what we should be using now for `data:; 50, expression_statement; 51, expression_statement; 52, comment:# Since we've already checked lines, we don't want to do it again; 53, expression_statement; 54, if_statement; 55, expression_statement; 56, expression_statement; 57, expression_statement; 58, expression_statement; 59, if_statement; 60, return_statement; 61, identifier:id_spec; 62, None; 63, identifier:force; 64, False; 65, identifier:verbose; 66, False; 67, identifier:checklines; 68, integer:10; 69, identifier:merge_strategy; 70, string; 71, identifier:transform; 72, None; 73, identifier:gtf_transcript_key; 74, string; 75, identifier:gtf_gene_key; 76, string; 77, identifier:gtf_subfeature; 78, string; 79, identifier:force_gff; 80, False; 81, identifier:force_dialect_check; 82, False; 83, identifier:from_string; 84, False; 85, identifier:keep_order; 86, False; 87, identifier:text_factory; 88, attribute; 89, identifier:force_merge_fields; 90, None; 91, identifier:pragmas; 92, attribute; 93, identifier:sort_attribute_values; 94, False; 95, identifier:dialect; 96, None; 97, identifier:_keep_tempfiles; 98, False; 99, identifier:infer_gene_extent; 100, True; 101, identifier:disable_infer_genes; 102, False; 103, identifier:disable_infer_transcripts; 104, False; 105, identifier:kwargs; 106, comment:"""
      Create a database from a GFF or GTF file.
  
      For more details on when and how to use the kwargs below, see the examples
      in the online documentation (:ref:`examples`).
  
      Parameters
      ----------
      data : string or iterable
  
          If a string (and `from_string` is False), then `data` is the path to
          the original GFF or GTF file.
  
          If a string and `from_string` is True, then assume `data` is the actual
          data to use.
  
          Otherwise, it's an iterable of Feature objects.
  
      dbfn : string
  
          Path to the database that will be created.  Can be the special string
          ":memory:" to create an in-memory database.
  
      id_spec : string, list, dict, callable, or None
  
          This parameter guides what will be used as the primary key for the
          database, which in turn determines how you will access individual
          features by name from the database.
  
          If `id_spec=None`, then auto-increment primary keys based on the
          feature type (e.g., "gene_1", "gene_2").  This is also the fallback
          behavior for the other values below.
  
          If `id_spec` is a string, then look for this key in the attributes.  If
          it exists, then use its value as the primary key, otherwise
          autoincrement based on the feature type.  For many GFF3 files, "ID"
          usually works well.
  
          If `id_spec` is a list or tuple of keys, then check for each one in
          order, using the first one found.  For GFF3, this might be ["ID",
          "Name"], which would use the ID if it exists, otherwise the Name,
          otherwise autoincrement based on the feature type.
  
          If `id_spec` is a dictionary, then it is a mapping of feature types to
          what should be used as the ID.  For example, for GTF files, `{'gene':
          'gene_id', 'transcript': 'transcript_id'}` may be useful.  The values
          of this dictionary can also be a list, e.g., `{'gene': ['gene_id',
          'geneID']}`
  
          If `id_spec` is a callable object, then it accepts a dictionary from
          the iterator and returns one of the following:
  
              * None (in which case the feature type will be auto-incremented)
              * string (which will be used as the primary key)
              * special string starting with "autoincrement:X", where "X" is
                a string that will be used for auto-incrementing.  For example,
                if "autoincrement:chr10", then the first feature will be
                "chr10_1", the second "chr10_2", and so on.
  
      force : bool
  
          If `False` (default), then raise an exception if `dbfn` already exists.
          Use `force=True` to overwrite any existing databases.
  
      verbose : bool
  
          Report percent complete and other feedback on how the db creation is
          progressing.
  
          In order to report percent complete, the entire file needs to be read
          once to see how many items there are; for large files you may want to
          use `verbose=False` to avoid this.
  
      checklines : int
  
          Number of lines to check the dialect.
  
      merge_strategy : str
          One of {merge, create_unique, error, warning, replace}.
  
          This parameter specifies the behavior when two items have an identical
          primary key.
  
          Using `merge_strategy="merge"`, then there will be a single entry in
          the database, but the attributes of all features with the same primary
          key will be merged.
  
          Using `merge_strategy="create_unique"`, then the first entry will use
          the original primary key, but the second entry will have a unique,
          autoincremented primary key assigned to it
  
          Using `merge_strategy="error"`, a :class:`gffutils.DuplicateID`
          exception will be raised.  This means you will have to edit the file
          yourself to fix the duplicated IDs.
  
          Using `merge_strategy="warning"`, a warning will be printed to the
          logger, and the duplicate feature will be skipped.
  
          Using `merge_strategy="replace"` will replace the entire existing
          feature with the new feature.
  
      transform : callable
  
          Function (or other callable object) that accepts a `Feature` object and
          returns a (possibly modified) `Feature` object.
  
      gtf_transcript_key, gtf_gene_key : string
  
          Which attribute to use as the transcript ID and gene ID respectively
          for GTF files.  Default is `transcript_id` and `gene_id` according to
          the GTF spec.
  
      gtf_subfeature : string
  
          Feature type to use as a "gene component" when inferring gene and
          transcript extents for GTF files.  Default is `exon` according to the
          GTF spec.
  
      force_gff : bool
          If True, do not do automatic format detection -- only use GFF.
  
      force_dialect_check : bool
          If True, the dialect will be checkef for every feature (instead of just
          `checklines` features).  This can be slow, but may be necessary for
          inconsistently-formatted input files.
  
      from_string : bool
          If True, then treat `data` as actual data (rather than the path to
          a file).
  
      keep_order : bool
  
          If True, all features returned from this instance will have the
          order of their attributes maintained.  This can be turned on or off
          database-wide by setting the `keep_order` attribute or with this
          kwarg, or on a feature-by-feature basis by setting the `keep_order`
          attribute of an individual feature.
  
          Note that a single order of attributes will be used for all features.
          Specifically, the order will be determined by the order of attribute
          keys in the first `checklines` of the input data. See
          helpers._choose_dialect for more information on this.
  
          Default is False, since this includes a sorting step that can get
          time-consuming for many features.
  
      infer_gene_extent : bool
          DEPRECATED in version 0.8.4. See `disable_infer_transcripts` and
          `disable_infer_genes` for more granular control.
  
      disable_infer_transcripts, disable_infer_genes : bool
          Only used for GTF files. By default -- and according to the GTF spec --
          we assume that there are no transcript or gene features in the file.
          gffutils then infers the extent of each transcript based on its
          constituent exons and infers the extent of each gene bases on its
          constituent transcripts.
  
          This default behavior is problematic if the input file already contains
          transcript or gene features (like recent GENCODE GTF files for human),
          since 1) the work to infer extents is unnecessary, and 2)
          trying to insert an inferred feature back into the database triggers
          gffutils' feature-merging routines, which can get time consuming.
  
          The solution is to use `disable_infer_transcripts=True` if your GTF
          already has transcripts in it, and/or `disable_infer_genes=True` if it
          already has genes in it. This can result in dramatic (100x) speedup.
  
          Prior to version 0.8.4, setting `infer_gene_extents=False` would
          disable both transcript and gene inference simultaneously. As of
          version 0.8.4, these argument allow more granular control.
  
      force_merge_fields : list
          If merge_strategy="merge", then features will only be merged if their
          non-attribute values are identical (same chrom, source, start, stop,
          score, strand, phase).  Using `force_merge_fields`, you can override
          this behavior to allow merges even when fields are different.  This
          list can contain one or more of ['seqid', 'source', 'featuretype',
          'score', 'strand', 'frame'].  The resulting merged fields will be
          strings of comma-separated values.  Note that 'start' and 'end' are not
          available, since these fields need to be integers.
  
      text_factory : callable
          Text factory to use for the sqlite3 database.  See
          https://docs.python.org/2/library/\
                  sqlite3.html#sqlite3.Connection.text_factory
          for details. The default sqlite3.OptimizedUnicode will return Unicode
          objects only for non-ASCII data, and bytestrings otherwise.
  
      pragmas : dict
          Dictionary of pragmas used when creating the sqlite3 database. See
          http://www.sqlite.org/pragma.html for a list of available pragmas.  The
          defaults are stored in constants.default_pragmas, which can be used as
          a template for supplying a custom dictionary.
  
      sort_attribute_values : bool
          All features returned from the database will have their attribute
          values sorted.  Typically this is only useful for testing, since this
          can get time-consuming for large numbers of features.
  
      _keep_tempfiles : bool or string
          False by default to clean up intermediate tempfiles created during GTF
          import.  If True, then keep these tempfile for testing or debugging.
          If string, then keep the tempfile for testing, but also use the string
          as the suffix fo the tempfile. This can be useful for testing in
          parallel environments.
  
      Returns
      -------
      New :class:`FeatureDB` object.
      """; 107, assignment; 108, call; 109, assignment; 110, assignment; 111, call; 112, comparison_operator:dialect is None; 113, block; 114, assignment; 115, assignment; 116, assignment; 117, boolean_operator; 118, block; 119, elif_clause; 120, call; 121, assignment; 122, assignment; 123, call; 124, comparison_operator:dbfn == ':memory:'; 125, block; 126, else_clause; 127, identifier:db; 128, string_content:error; 129, string_content:transcript_id; 130, string_content:gene_id; 131, string_content:exon; 132, identifier:sqlite3; 133, identifier:OptimizedUnicode; 134, identifier:constants; 135, identifier:default_pragmas; 136, identifier:_locals; 137, call; 138, identifier:deprecation_handler; 139, argument_list; 140, identifier:kwargs; 141, call; 142, identifier:iterator; 143, call; 144, attribute; 145, argument_list; 146, identifier:dialect; 147, None; 148, expression_statement; 149, subscript; 150, attribute; 151, subscript; 152, attribute; 153, subscript; 154, integer:0; 155, identifier:force_gff; 156, parenthesized_expression; 157, expression_statement; 158, expression_statement; 159, expression_statement; 160, comparison_operator:dialect['fmt'] == 'gtf'; 161, block; 162, attribute; 163, argument_list; 164, subscript; 165, identifier:dialect; 166, identifier:c; 167, call; 168, attribute; 169, argument_list; 170, identifier:dbfn; 171, string; 172, expression_statement; 173, block; 174, identifier:locals; 175, argument_list; 176, identifier:kwargs; 177, identifier:dict; 178, generator_expression; 179, attribute; 180, argument_list; 181, identifier:kwargs; 182, identifier:update; 183, dictionary_splat; 184, assignment; 185, identifier:kwargs; 186, string; 187, identifier:iterator; 188, identifier:_iter; 189, identifier:kwargs; 190, string; 191, identifier:iterator; 192, identifier:directives; 193, identifier:kwargs; 194, string; 195, comparison_operator:dialect['fmt'] == 'gff3'; 196, assignment; 197, assignment; 198, assignment; 199, subscript; 200, string; 201, expression_statement; 202, expression_statement; 203, expression_statement; 204, identifier:kwargs; 205, identifier:update; 206, dictionary_splat; 207, identifier:kwargs; 208, string; 209, identifier:cls; 210, argument_list; 211, identifier:c; 212, identifier:create; 213, string_content::memory:; 214, assignment; 215, expression_statement; 216, tuple; 217, for_in_clause; 218, identifier:iterators; 219, identifier:DataIterator; 220, dictionary_splat; 221, identifier:_locals; 222, identifier:dialect; 223, attribute; 224, string_content:data; 225, string_content:directives; 226, string_content:checklines; 227, subscript; 228, string; 229, identifier:cls; 230, identifier:_GFFDBCreator; 231, identifier:id_spec; 232, boolean_operator; 233, identifier:add_kwargs; 234, call; 235, identifier:dialect; 236, string; 237, string_content:gtf; 238, assignment; 239, assignment; 240, assignment; 241, identifier:add_kwargs; 242, string_content:dialect; 243, dictionary_splat; 244, identifier:db; 245, call; 246, assignment; 247, identifier:i; 248, subscript; 249, identifier:i; 250, attribute; 251, identifier:kwargs; 252, identifier:iterator; 253, identifier:dialect; 254, identifier:dialect; 255, string; 256, string_content:gff3; 257, identifier:id_spec; 258, string; 259, identifier:dict; 260, argument_list; 261, string_content:fmt; 262, identifier:cls; 263, identifier:_GTFDBCreator; 264, identifier:id_spec; 265, boolean_operator; 266, identifier:add_kwargs; 267, call; 268, identifier:kwargs; 269, attribute; 270, argument_list; 271, identifier:db; 272, call; 273, identifier:_locals; 274, identifier:i; 275, identifier:constants; 276, identifier:_iterator_kwargs; 277, string_content:fmt; 278, string_content:ID; 279, keyword_argument; 280, identifier:id_spec; 281, dictionary; 282, identifier:dict; 283, argument_list; 284, identifier:interface; 285, identifier:FeatureDB; 286, attribute; 287, keyword_argument; 288, keyword_argument; 289, keyword_argument; 290, keyword_argument; 291, attribute; 292, argument_list; 293, identifier:id_spec; 294, identifier:id_spec; 295, pair; 296, pair; 297, keyword_argument; 298, keyword_argument; 299, keyword_argument; 300, keyword_argument; 301, identifier:c; 302, identifier:conn; 303, identifier:keep_order; 304, identifier:keep_order; 305, identifier:pragmas; 306, identifier:pragmas; 307, identifier:sort_attribute_values; 308, identifier:sort_attribute_values; 309, identifier:text_factory; 310, identifier:text_factory; 311, identifier:interface; 312, identifier:FeatureDB; 313, identifier:c; 314, keyword_argument; 315, keyword_argument; 316, keyword_argument; 317, keyword_argument; 318, string; 319, string; 320, string; 321, string; 322, identifier:transcript_key; 323, identifier:gtf_transcript_key; 324, identifier:gene_key; 325, identifier:gtf_gene_key; 326, identifier:subfeature; 327, identifier:gtf_subfeature; 328, identifier:id_spec; 329, identifier:id_spec; 330, identifier:keep_order; 331, identifier:keep_order; 332, identifier:pragmas; 333, identifier:pragmas; 334, identifier:sort_attribute_values; 335, identifier:sort_attribute_values; 336, identifier:text_factory; 337, identifier:text_factory; 338, string_content:gene; 339, string_content:gene_id; 340, string_content:transcript; 341, string_content:transcript_id
code: def create_db(data, dbfn, id_spec=None, force=False, verbose=False,
                checklines=10, merge_strategy='error', transform=None,
                gtf_transcript_key='transcript_id', gtf_gene_key='gene_id',
                gtf_subfeature='exon', force_gff=False,
                force_dialect_check=False, from_string=False, keep_order=False,
                text_factory=sqlite3.OptimizedUnicode, force_merge_fields=None,
                pragmas=constants.default_pragmas, sort_attribute_values=False,
                dialect=None, _keep_tempfiles=False, infer_gene_extent=True,
                disable_infer_genes=False, disable_infer_transcripts=False,
                **kwargs):
      """
      Create a database from a GFF or GTF file.
  
      For more details on when and how to use the kwargs below, see the examples
      in the online documentation (:ref:`examples`).
  
      Parameters
      ----------
      data : string or iterable
  
          If a string (and `from_string` is False), then `data` is the path to
          the original GFF or GTF file.
  
          If a string and `from_string` is True, then assume `data` is the actual
          data to use.
  
          Otherwise, it's an iterable of Feature objects.
  
      dbfn : string
  
          Path to the database that will be created.  Can be the special string
          ":memory:" to create an in-memory database.
  
      id_spec : string, list, dict, callable, or None
  
          This parameter guides what will be used as the primary key for the
          database, which in turn determines how you will access individual
          features by name from the database.
  
          If `id_spec=None`, then auto-increment primary keys based on the
          feature type (e.g., "gene_1", "gene_2").  This is also the fallback
          behavior for the other values below.
  
          If `id_spec` is a string, then look for this key in the attributes.  If
          it exists, then use its value as the primary key, otherwise
          autoincrement based on the feature type.  For many GFF3 files, "ID"
          usually works well.
  
          If `id_spec` is a list or tuple of keys, then check for each one in
          order, using the first one found.  For GFF3, this might be ["ID",
          "Name"], which would use the ID if it exists, otherwise the Name,
          otherwise autoincrement based on the feature type.
  
          If `id_spec` is a dictionary, then it is a mapping of feature types to
          what should be used as the ID.  For example, for GTF files, `{'gene':
          'gene_id', 'transcript': 'transcript_id'}` may be useful.  The values
          of this dictionary can also be a list, e.g., `{'gene': ['gene_id',
          'geneID']}`
  
          If `id_spec` is a callable object, then it accepts a dictionary from
          the iterator and returns one of the following:
  
              * None (in which case the feature type will be auto-incremented)
              * string (which will be used as the primary key)
              * special string starting with "autoincrement:X", where "X" is
                a string that will be used for auto-incrementing.  For example,
                if "autoincrement:chr10", then the first feature will be
                "chr10_1", the second "chr10_2", and so on.
  
      force : bool
  
          If `False` (default), then raise an exception if `dbfn` already exists.
          Use `force=True` to overwrite any existing databases.
  
      verbose : bool
  
          Report percent complete and other feedback on how the db creation is
          progressing.
  
          In order to report percent complete, the entire file needs to be read
          once to see how many items there are; for large files you may want to
          use `verbose=False` to avoid this.
  
      checklines : int
  
          Number of lines to check the dialect.
  
      merge_strategy : str
          One of {merge, create_unique, error, warning, replace}.
  
          This parameter specifies the behavior when two items have an identical
          primary key.
  
          Using `merge_strategy="merge"`, then there will be a single entry in
          the database, but the attributes of all features with the same primary
          key will be merged.
  
          Using `merge_strategy="create_unique"`, then the first entry will use
          the original primary key, but the second entry will have a unique,
          autoincremented primary key assigned to it
  
          Using `merge_strategy="error"`, a :class:`gffutils.DuplicateID`
          exception will be raised.  This means you will have to edit the file
          yourself to fix the duplicated IDs.
  
          Using `merge_strategy="warning"`, a warning will be printed to the
          logger, and the duplicate feature will be skipped.
  
          Using `merge_strategy="replace"` will replace the entire existing
          feature with the new feature.
  
      transform : callable
  
          Function (or other callable object) that accepts a `Feature` object and
          returns a (possibly modified) `Feature` object.
  
      gtf_transcript_key, gtf_gene_key : string
  
          Which attribute to use as the transcript ID and gene ID respectively
          for GTF files.  Default is `transcript_id` and `gene_id` according to
          the GTF spec.
  
      gtf_subfeature : string
  
          Feature type to use as a "gene component" when inferring gene and
          transcript extents for GTF files.  Default is `exon` according to the
          GTF spec.
  
      force_gff : bool
          If True, do not do automatic format detection -- only use GFF.
  
      force_dialect_check : bool
          If True, the dialect will be checkef for every feature (instead of just
          `checklines` features).  This can be slow, but may be necessary for
          inconsistently-formatted input files.
  
      from_string : bool
          If True, then treat `data` as actual data (rather than the path to
          a file).
  
      keep_order : bool
  
          If True, all features returned from this instance will have the
          order of their attributes maintained.  This can be turned on or off
          database-wide by setting the `keep_order` attribute or with this
          kwarg, or on a feature-by-feature basis by setting the `keep_order`
          attribute of an individual feature.
  
          Note that a single order of attributes will be used for all features.
          Specifically, the order will be determined by the order of attribute
          keys in the first `checklines` of the input data. See
          helpers._choose_dialect for more information on this.
  
          Default is False, since this includes a sorting step that can get
          time-consuming for many features.
  
      infer_gene_extent : bool
          DEPRECATED in version 0.8.4. See `disable_infer_transcripts` and
          `disable_infer_genes` for more granular control.
  
      disable_infer_transcripts, disable_infer_genes : bool
          Only used for GTF files. By default -- and according to the GTF spec --
          we assume that there are no transcript or gene features in the file.
          gffutils then infers the extent of each transcript based on its
          constituent exons and infers the extent of each gene bases on its
          constituent transcripts.
  
          This default behavior is problematic if the input file already contains
          transcript or gene features (like recent GENCODE GTF files for human),
          since 1) the work to infer extents is unnecessary, and 2)
          trying to insert an inferred feature back into the database triggers
          gffutils' feature-merging routines, which can get time consuming.
  
          The solution is to use `disable_infer_transcripts=True` if your GTF
          already has transcripts in it, and/or `disable_infer_genes=True` if it
          already has genes in it. This can result in dramatic (100x) speedup.
  
          Prior to version 0.8.4, setting `infer_gene_extents=False` would
          disable both transcript and gene inference simultaneously. As of
          version 0.8.4, these argument allow more granular control.
  
      force_merge_fields : list
          If merge_strategy="merge", then features will only be merged if their
          non-attribute values are identical (same chrom, source, start, stop,
          score, strand, phase).  Using `force_merge_fields`, you can override
          this behavior to allow merges even when fields are different.  This
          list can contain one or more of ['seqid', 'source', 'featuretype',
          'score', 'strand', 'frame'].  The resulting merged fields will be
          strings of comma-separated values.  Note that 'start' and 'end' are not
          available, since these fields need to be integers.
  
      text_factory : callable
          Text factory to use for the sqlite3 database.  See
          https://docs.python.org/2/library/\
                  sqlite3.html#sqlite3.Connection.text_factory
          for details. The default sqlite3.OptimizedUnicode will return Unicode
          objects only for non-ASCII data, and bytestrings otherwise.
  
      pragmas : dict
          Dictionary of pragmas used when creating the sqlite3 database. See
          http://www.sqlite.org/pragma.html for a list of available pragmas.  The
          defaults are stored in constants.default_pragmas, which can be used as
          a template for supplying a custom dictionary.
  
      sort_attribute_values : bool
          All features returned from the database will have their attribute
          values sorted.  Typically this is only useful for testing, since this
          can get time-consuming for large numbers of features.
  
      _keep_tempfiles : bool or string
          False by default to clean up intermediate tempfiles created during GTF
          import.  If True, then keep these tempfile for testing or debugging.
          If string, then keep the tempfile for testing, but also use the string
          as the suffix fo the tempfile. This can be useful for testing in
          parallel environments.
  
      Returns
      -------
      New :class:`FeatureDB` object.
      """
      _locals = locals()
  
      # Check if any older kwargs made it in
      deprecation_handler(kwargs)
  
      kwargs = dict((i, _locals[i]) for i in constants._iterator_kwargs)
  
      # First construct an iterator so that we can identify the file format.
      # DataIterator figures out what kind of data was provided (string of lines,
      # filename, or iterable of Features) and checks `checklines` lines to
      # identify the dialect.
      iterator = iterators.DataIterator(**kwargs)
  
      kwargs.update(**_locals)
  
      if dialect is None:
          dialect = iterator.dialect
  
      # However, a side-effect of this is that  if `data` was a generator, then
      # we've just consumed `checklines` items (see
      # iterators.BaseIterator.__init__, which calls iterators.peek).
      #
      # But it also chains those consumed items back onto the beginning, and the
      # result is available as as iterator._iter.
      #
      # That's what we should be using now for `data:
      kwargs['data'] = iterator._iter
      kwargs['directives'] = iterator.directives
  
      # Since we've already checked lines, we don't want to do it again
      kwargs['checklines'] = 0
  
      if force_gff or (dialect['fmt'] == 'gff3'):
          cls = _GFFDBCreator
          id_spec = id_spec or 'ID'
          add_kwargs = dict(
              id_spec=id_spec,
          )
  
      elif dialect['fmt'] == 'gtf':
          cls = _GTFDBCreator
          id_spec = id_spec or {'gene': 'gene_id', 'transcript': 'transcript_id'}
          add_kwargs = dict(
              transcript_key=gtf_transcript_key,
              gene_key=gtf_gene_key,
              subfeature=gtf_subfeature,
              id_spec=id_spec,
          )
  
      kwargs.update(**add_kwargs)
      kwargs['dialect'] = dialect
      c = cls(**kwargs)
  
      c.create()
      if dbfn == ':memory:':
          db = interface.FeatureDB(c.conn,
                                   keep_order=keep_order,
                                   pragmas=pragmas,
                                   sort_attribute_values=sort_attribute_values,
                                   text_factory=text_factory)
      else:
          db = interface.FeatureDB(c,
                                   keep_order=keep_order,
                                   pragmas=pragmas,
                                   sort_attribute_values=sort_attribute_values,
                                   text_factory=text_factory)
  
      return db