def _resymbolStockMetrics(oldSymbol, newSymbol):
  """ Resymbol stock metrics

  :param str oldSymbol: old stock symbol, upper case
  :param str newSymbol: new stock symbol, upper case
  """
  g_log.info("Renaming stock metrics: oldSymbol=%s, newSymbol=%s",
             oldSymbol, newSymbol)

  sqlEngine = collectorsdb.engineFactory()


  with sqlEngine.begin() as conn:
    # NOTE: the foreign key cascade-on-update relationship between
    # emitted_stock_price, emitted_stock_volume, xignite_security_bars, and the
    # xignite_security tables causes the symbol to be automatically updated or
    # the corresponding rows to be deleted in the former tables when the symbol
    # in xignite_security table is updated or deleted.

    # Delete emitted stock price rows for old symbol
    conn.execute(
      schema.emittedStockPrice  # pylint: disable=E1120
      .delete()
      .where(schema.emittedStockPrice.c.symbol == oldSymbol)
    )

    # Delete emitted stock volume rows for old symbol
    conn.execute(
      schema.emittedStockVolume  # pylint: disable=E1120
      .delete()
      .where(schema.emittedStockVolume.c.symbol == oldSymbol)
    )

    # Re-symbol xignite security row associated with the old symbol
    #
    # NOTE: we use IGNORE to ignore integrity errors (most likely duplicate),
    # because stock agent might insert a security row for the new symbol before
    # we do.
    conn.execute(
      schema.xigniteSecurity  # pylint: disable=E1120
      .update().prefix_with('IGNORE', dialect="mysql")
      .where(schema.xigniteSecurity.c.symbol == oldSymbol)
      .values(symbol=newSymbol)
    )
    # Delete old xignite security row just in case the rename aborted due to
    # integrity error
    conn.execute(
      schema.xigniteSecurity  # pylint: disable=E1120
      .delete()
      .where(schema.xigniteSecurity.c.symbol == oldSymbol)
    )

  # Forward stock metric data samples to Taurus Engine
  g_log.info("Forwarding new stock metric data samples for symbol=%s to Taurus "
             "engine...", newSymbol)
  xignite_stock_agent.transmitMetricData(
    metricSpecs=[spec for spec
                 in xignite_stock_agent.loadMetricSpecs()
                 if spec.symbol == newSymbol],
    symbol=newSymbol,
    engine=sqlEngine
  )
def _resymbolStockMetrics(oldSymbol, newSymbol):
  """ Resymbol stock metrics

  :param str oldSymbol: old stock symbol, upper case
  :param str newSymbol: new stock symbol, upper case
  """
  g_log.info("Renaming stock metrics: oldSymbol=%s, newSymbol=%s",
             oldSymbol, newSymbol)

  sqlEngine = collectorsdb.engineFactory()


  with sqlEngine.begin() as conn:
    # NOTE: the foreign key cascade-on-update relationship between
    # emitted_stock_price/emitted_stock_volume tables and the
    # xignite_security_bars table causes the symbol to be automatically updated
    # in the xignite_security_* tables

    # Delete emitted stock price rows for old symbol
    conn.execute(
      schema.emittedStockPrice  # pylint: disable=E1120
      .delete()
      .where(schema.emittedStockPrice.c.symbol == oldSymbol)
    )

    # Delete emitted stock volume rows for old symbol
    conn.execute(
      schema.emittedStockVolume  # pylint: disable=E1120
      .delete()
      .where(schema.emittedStockVolume.c.symbol == oldSymbol)
    )

    # Re-symbol xignite security row associated with the old symbol
    #
    # TODO TAUR-1327: when we rename this symbol in the xignite_security table,
    # we leave other columns of the affected xignite_security row likely
    # inconsitent with the new symbol, which is bad. Once TAUR-1327 is complete,
    # this problem will go away along with this operation on xignite_security
    # table.
    #
    # NOTE: we use IGNORE to ignore integrity errors (most likely duplicate),
    # because stock agent might insert a security row for the new symbol before
    # we do.
    conn.execute(
      schema.xigniteSecurity  # pylint: disable=E1120
      .update().prefix_with('IGNORE', dialect="mysql")
      .where(schema.xigniteSecurity.c.symbol == oldSymbol)
      .values(symbol=newSymbol)
    )
    # Delete old xignite security row just in case the rename aborted due to
    # integrity error
    conn.execute(
      schema.xigniteSecurity  # pylint: disable=E1120
      .delete()
      .where(schema.xigniteSecurity.c.symbol == oldSymbol)
    )

    # Update stock bars
    # NOTE: This becomes necessary once TAUR-1327 is implemented
    conn.execute(
      schema.xigniteSecurityBars  # pylint: disable=E1120
      .update()
      .where(schema.xigniteSecurityBars.c.symbol == oldSymbol)
      .values(symbol=newSymbol))

  # Forward stock metric data samples to Taurus Engine
  g_log.info("Forwarding new stock metric data samples for symbol=%s to Taurus "
             "engine...", newSymbol)
  xignite_stock_agent.transmitMetricData(
    metricSpecs=[spec for spec
                 in xignite_stock_agent.loadMetricSpecs()
                 if spec.symbol == newSymbol],
      symbol=newSymbol,
      engine=sqlEngine
  )