docs: def insert_penalty_model(cur, penalty_model):
      """Insert a penalty model into the database.
  
      Args:
          cur (:class:`sqlite3.Cursor`): An sqlite3 cursor. This function
              is meant to be run within a :obj:`with` statement.
          penalty_model (:class:`penaltymodel.PenaltyModel`): A penalty
              model to be stored in the database.
  
      Examples:
          >>> import networkx as nx
          >>> import penaltymodel.core as pm
          >>> import dimod
          >>> graph = nx.path_graph(3)
          >>> decision_variables = (0, 2)
          >>> feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
          >>> spec = pm.Specification(graph, decision_variables, feasible_configurations, dimod.SPIN)
          >>> linear = {v: 0 for v in graph}
          >>> quadratic = {edge: -1 for edge in graph.edges}
          >>> model = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, vartype=dimod.SPIN)
          >>> widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)
          >>> with pmc.cache_connect(':memory:') as cur:
          ...     pmc.insert_penalty_model(cur, widget)
  
      """
      encoded_data = {}
  
      linear, quadratic, offset = penalty_model.model.to_ising()
      nodelist = sorted(linear)
      edgelist = sorted(sorted(edge) for edge in penalty_model.graph.edges)
  
      insert_graph(cur, nodelist, edgelist, encoded_data)
      insert_feasible_configurations(cur, penalty_model.feasible_configurations, encoded_data)
      insert_ising_model(cur, nodelist, edgelist, linear, quadratic, offset, encoded_data)
  
      encoded_data['decision_variables'] = json.dumps(penalty_model.decision_variables, separators=(',', ':'))
      encoded_data['classical_gap'] = penalty_model.classical_gap
      encoded_data['ground_energy'] = penalty_model.ground_energy
  
      insert = \
          """
          INSERT OR IGNORE INTO penalty_model(
              decision_variables,
              classical_gap,
              ground_energy,
              feasible_configurations_id,
              ising_model_id)
          SELECT
              :decision_variables,
              :classical_gap,
              :ground_energy,
              feasible_configurations.id,
              ising_model.id
          FROM feasible_configurations, ising_model, graph
          WHERE
              graph.edges = :edges AND
              graph.num_nodes = :num_nodes AND
              ising_model.graph_id = graph.id AND
              ising_model.linear_biases = :linear_biases AND
              ising_model.quadratic_biases = :quadratic_biases AND
              ising_model.offset = :offset AND
              feasible_configurations.num_variables = :num_variables AND
              feasible_configurations.num_feasible_configurations = :num_feasible_configurations AND
              feasible_configurations.feasible_configurations = :feasible_configurations AND
              feasible_configurations.energies = :energies;
          """
  
      cur.execute(insert, encoded_data)