class_docstr: Helper class to convert between `Range` and PostgreSQL range types.
  
  Objects of this class are usually created by `register_range()`. Manual
  creation could be useful if querying the database is not advisable: in
  this case the oids must be provided.
class_docstr_tok: ["Helper","class","to","convert","between","`","Range","`","and","PostgreSQL","range","types",".","Objects","of","this","class","are","usually","created","by","`","register_range","(",")","`",".","Manual","creation","could","be","useful","if","querying","the","database","is","not","advisable",":","in","this","case","the","oids","must","be","provided","."]
docstr: Return a `RangeCaster` instance for the type *pgrange*.
  
  Raise `ProgrammingError` if the type is not found.
docstr_tok: ["Return","a","`","RangeCaster","`","instance","for","the","type","*","pgrange","*",".","Raise","`","ProgrammingError","`","if","the","type","is","not","found","."]
code: def _from_db(self, name, pyrange, conn_or_curs):
      """Return a `RangeCaster` instance for the type *pgrange*.
  
      Raise `ProgrammingError` if the type is not found.
      """
      from psycopg2.extensions import STATUS_IN_TRANSACTION
      from psycopg2.extras import _solve_conn_curs
  
      conn, curs = _solve_conn_curs(conn_or_curs)
  
      if conn.info.server_version < 90200:
          raise ProgrammingError(
              "range types not available in version %s"
              % conn.info.server_version
          )
  
      # Store the transaction status of the connection to revert it after use
      conn_status = conn.status
  
      # Use the correct schema
      if "." in name:
          schema, tname = name.split(".", 1)
      else:
          tname = name
          schema = "public"
  
      # get the type oid and attributes
      curs.execute(
          """\
  select rngtypid, rngsubtype, typarray
  from pg_range r
  join pg_type t on t.oid = rngtypid
  join pg_namespace ns on ns.oid = typnamespace
  where typname = %s and ns.nspname = %s;
  """,
          (tname, schema),
      )
      rec = curs.fetchone()
  
      if not rec:
          # The above algorithm doesn't work for customized seach_path
          # (#1487) The implementation below works better, but, to guarantee
          # backwards compatibility, use it only if the original one failed.
          try:
              savepoint = False
              # Because we executed statements earlier, we are either INTRANS
              # or we are IDLE only if the transaction is autocommit, in
              # which case we don't need the savepoint anyway.
              if conn.status == STATUS_IN_TRANSACTION:
                  curs.execute("SAVEPOINT register_type")
                  savepoint = True
  
              curs.execute(
                  """\
  SELECT rngtypid, rngsubtype, typarray, typname, nspname
  from pg_range r
  join pg_type t on t.oid = rngtypid
  join pg_namespace ns on ns.oid = typnamespace
  WHERE t.oid = %s::regtype
  """,
                  (name,),
              )
          except ProgrammingError:
              pass
          else:
              rec = curs.fetchone()
              if rec:
                  tname, schema = rec[3:]
          finally:
              if savepoint:
                  curs.execute("ROLLBACK TO SAVEPOINT register_type")
  
      # revert the status of the connection as before the command
      if conn_status != STATUS_IN_TRANSACTION and not conn.autocommit:
          conn.rollback()
  
      if not rec:
          raise ProgrammingError(f"PostgreSQL range '{name}' not found")
  
      type, subtype, array = rec[:3]
  
      return RangeCaster(
          name, pyrange, oid=type, subtype_oid=subtype, array_oid=array
      )
  
imports: import re
  from psycopg2._psycopg import ProgrammingError, InterfaceError
  from psycopg2.extensions import ISQLQuote, adapt, register_adapter
  from psycopg2.extensions import new_type, new_array_type, register_type
label_desc: Use image node_id 3 for calling the RangeCaster obj's underlying member method code with example usage: obj._from_db(name, pyrange, conn_or_curs) and returns: RangeCaster