class_docstr: Interact with odbc data sources using pyodbc.
  
  To configure driver, in addition to supplying as constructor arg, the following are also supported:
      * set ``driver`` parameter in ``hook_params`` dictionary when instantiating hook by SQL operators.
      * set ``driver`` extra in the connection and set ``allow_driver_in_extra`` to True in
        section ``providers.odbc`` section of airflow config.
      * patch ``OdbcHook.default_driver`` in ``local_settings.py`` file.
  
  See :doc:`/connections/odbc` for full documentation.
  
  :param args: passed to DbApiHook
  :param database: database to use -- overrides connection ``schema``
  :param driver: name of driver or path to driver. see above for more info
  :param dsn: name of DSN to use.  overrides DSN supplied in connection ``extra``
  :param connect_kwargs: keyword arguments passed to ``pyodbc.connect``
  :param sqlalchemy_scheme: Scheme sqlalchemy connection.  Default is ``mssql+pyodbc`` Only used for
      ``get_sqlalchemy_engine`` and ``get_sqlalchemy_connection`` methods.
  :param kwargs: passed to DbApiHook
docstr: ODBC connection string.
  
  We build connection string instead of using ``pyodbc.connect`` params
  because, for example, there is no param representing
  ``ApplicationIntent=ReadOnly``.  Any key-value pairs provided in
  ``Connection.extra`` will be added to the connection string.
docstr_tok: ["ODBC","connection","string",".","We","build","connection","string","instead","of","using","``","pyodbc.connect","``","params","because",",","for","example",",","there","is","no","param","representing","``","ApplicationIntent=ReadOnly","``",".","Any","key-value","pairs","provided","in","``","Connection.extra","``","will","be","added","to","the","connection","string","."]
code: def odbc_connection_string(self):
      """ODBC connection string.
  
      We build connection string instead of using ``pyodbc.connect`` params
      because, for example, there is no param representing
      ``ApplicationIntent=ReadOnly``.  Any key-value pairs provided in
      ``Connection.extra`` will be added to the connection string.
      """
      if not self._conn_str:
          conn_str = ""
          if self.driver:
              conn_str += f"DRIVER={{{self.driver}}};"
          if self.dsn:
              conn_str += f"DSN={self.dsn};"
          if self.connection.host:
              conn_str += f"SERVER={self.connection.host};"
          database = self.database or self.connection.schema
          if database:
              conn_str += f"DATABASE={database};"
          if self.connection.login:
              conn_str += f"UID={self.connection.login};"
          if self.connection.password:
              conn_str += f"PWD={self.connection.password};"
          if self.connection.port:
              conn_str += f"PORT={self.connection.port};"
  
          extra_exclude = {
              "driver",
              "dsn",
              "connect_kwargs",
              "sqlalchemy_scheme",
              "placeholder",
          }
          extra_params = {
              k: v
              for k, v in self.connection.extra_dejson.items()
              if k.lower() not in extra_exclude
          }
          for k, v in extra_params.items():
              conn_str += f"{k}={v};"
  
          self._conn_str = conn_str
      return self._conn_str
  
imports: from __future__ import annotations
  from typing import Any, List, NamedTuple, Sequence, cast
  from urllib.parse import quote_plus
  from pyodbc import Connection, Row, connect
  from airflow.providers.common.sql.hooks.sql import DbApiHook
  from airflow.utils.helpers import merge_dicts
label_desc: Use image node_id 8 for calling the OdbcHook obj's underlying member method code with example usage: obj.odbc_connection_string() and returns: self