# Buggy code
def create_connect_args(self, url):
    opts = url.translate_connect_args(username="user")
    opts.update(url.query)

    keys = opts

    query = url.query

    connect_args = {}
    for param in ("ansi", "unicode_results", "autocommit"):
        if param in keys:
            connect_args[param] = util.asbool(keys.pop(param))

    if "odbc_connect" in keys:
        connectors = [util.unquote_plus(keys.pop("odbc_connect"))]
    else:

        def check_quote(token):
            if ";" in str(token):
                token = "'%s'" % token
            return token

        keys = dict((k, check_quote(v)) for k, v in keys.items())

        dsn_connection = "dsn" in keys or ("host" in keys and "database" not in keys)
        if dsn_connection:
            connectors = ["dsn=%s" % (keys.pop("host", "") or keys.pop("dsn", ""))]
        else:
            port = ""
            if "port" in keys and "port" not in query:
                port = ",%d" % int(keys.pop("port"))

            connectors = []
            driver = keys.pop("driver", self.pyodbc_driver_name)
            if driver is None and keys:
                # note if keys is empty, this is a totally blank URL
                util.warn(
                    "No driver name specified; "
                    "this is expected by PyODBC when using "
                    "DSN-less connections"
                )
            else:
                connectors.append("DRIVER={%s}" % driver)

            connectors.extend(
                [
                    "Server=%s%s" % (keys.pop("host", ""), port),
                    "Database=%s" % keys.pop("database", ""),
                ]
            )

        user = keys.pop("user", None)
        if user:
            connectors.append("UID=%s" % user)
            connectors.append("PWD=%s" % keys.pop("password", ""))
        else:
            connectors.append("Trusted_Connection=Yes")

        # if set to 'Yes', the ODBC layer will try to automagically
        # convert textual data from your database encoding to your
        # client encoding.  This should obviously be set to 'No' if
        # you query a cp1253 encoded database from a latin1 client...
        if "odbc_autotranslate" in keys:
            connectors.append("AutoTranslate=%s" % keys.pop("odbc_autotranslate"))

        connectors.extend(["%s=%s" % (k, v) for k, v in keys.items()])

    return [[";".join(connectors)], connect_args]


# Traceback (InterfaceError)
InterfaceError                            Traceback (most recent call last)
/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/base.py in _wrap_pool_connect(self, fn, connection)
2344         try:
-> 2345             return fn()
2346         except dialect.dbapi.Error as e:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in connect(self)
363         if not self._use_threadlocal:
--> 364             return _ConnectionFairy._checkout(self)
365

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in _checkout(cls, pool, threadconns, fairy)
777         if not fairy:
--> 778             fairy = _ConnectionRecord.checkout(pool)
779

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in checkout(cls, pool)
494     def checkout(cls, pool):
--> 495         rec = pool._do_get()
496         try:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/impl.py in _do_get(self)
139                 with util.safe_reraise():
--> 140                     self._dec_overflow()
141         else:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py in __exit__(self, type_, value, traceback)
68                 compat.raise_(
---> 69                     exc_value, with_traceback=exc_tb,
70                 )

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
177         try:
--> 178             raise exception
179         finally:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/impl.py in _do_get(self)
136             try:
--> 137                 return self._create_connection()
138             except:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in _create_connection(self)
308
--> 309         return _ConnectionRecord(self)
310

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in __init__(self, pool, connect)
439         if connect:
--> 440             self.__connect(first_connect_check=True)
441         self.finalize_callback = deque()

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in __connect(self, first_connect_check)
660             with util.safe_reraise():
--> 661                 pool.logger.debug("Error on connect(): %s", e)
662         else:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py in __exit__(self, type_, value, traceback)
68                 compat.raise_(
---> 69                     exc_value, with_traceback=exc_tb,
70                 )

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
177         try:
--> 178             raise exception
179         finally:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in __connect(self, first_connect_check)
655             self.starttime = time.time()
--> 656             connection = pool._invoke_creator(self)
657             pool.logger.debug("Created new connection %r", connection)

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/strategies.py in connect(connection_record)
113                             return connection
--> 114                 return dialect.connect(*cargs, **cparams)
115

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/default.py in connect(self, *cargs, **cparams)
489         # inherits the docstring from interfaces.Dialect.connect
--> 490         return self.dbapi.connect(*cargs, **cparams)
491

InterfaceError: ('28000', "[28000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Login failed for user 'username'. (18456) (SQLDriverConnect)")

The above exception was the direct cause of the following exception:

InterfaceError                            Traceback (most recent call last)
<ipython-input-7-a96561cd5686> in <module>
----> 1 df.to_sql("Test", connection1, 'username', if_exists='append')

/opt/conda/lib/python3.7/site-packages/pandas/core/generic.py in to_sql(self, name, con, schema, if_exists, index, index_label, chunksize, dtype, method)
2661             chunksize=chunksize,
2662             dtype=dtype,
-> 2663             method=method,
2664         )
2665

/opt/conda/lib/python3.7/site-packages/pandas/io/sql.py in to_sql(frame, name, con, schema, if_exists, index, index_label, chunksize, dtype, method)
519         chunksize=chunksize,
520         dtype=dtype,
--> 521         method=method,
522     )
523

/opt/conda/lib/python3.7/site-packages/pandas/io/sql.py in to_sql(self, frame, name, if_exists, index, index_label, schema, chunksize, dtype, method)
1314             dtype=dtype,
1315         )
-> 1316         table.create()
1317         table.insert(chunksize, method=method)
1318         if not name.isdigit() and not name.islower():

/opt/conda/lib/python3.7/site-packages/pandas/io/sql.py in create(self)
642
643     def create(self):
--> 644         if self.exists():
645             if self.if_exists == "fail":
646                 raise ValueError(f"Table '{self.name}' already exists.")

/opt/conda/lib/python3.7/site-packages/pandas/io/sql.py in exists(self)
629
630     def exists(self):
--> 631         return self.pd_sql.has_table(self.name, self.schema)
632
633     def sql_schema(self):

/opt/conda/lib/python3.7/site-packages/pandas/io/sql.py in has_table(self, name, schema)
1339     def has_table(self, name, schema=None):
1340         return self.connectable.run_callable(
-> 1341             self.connectable.dialect.has_table, name, schema or self.meta.schema
1342         )
1343

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/base.py in run_callable(self, callable_, *args, **kwargs)
2218
2219         """
-> 2220         with self._contextual_connect() as conn:
2221             return conn.run_callable(callable_, *args, **kwargs)
2222

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/base.py in _contextual_connect(self, close_with_result, **kwargs)
2309         return self._connection_cls(
2310             self,
-> 2311             self._wrap_pool_connect(self.pool.connect, None),
2312             close_with_result=close_with_result,
2313             **kwargs

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/base.py in _wrap_pool_connect(self, fn, connection)
2347             if connection is None:
2348                 Connection._handle_dbapi_exception_noconnection(
-> 2349                     e, dialect, self
2350                 )
2351             else:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/base.py in _handle_dbapi_exception_noconnection(cls, e, dialect, engine)
1589         elif should_wrap:
1590             util.raise_(
-> 1591                 sqlalchemy_exception, with_traceback=exc_info[2], from_=e
1592             )
1593         else:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
176
177         try:
--> 178             raise exception
179         finally:
180             # credit to

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/base.py in _wrap_pool_connect(self, fn, connection)
2343         dialect = self.dialect
2344         try:
-> 2345             return fn()
2346         except dialect.dbapi.Error as e:
2347             if connection is None:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in connect(self)
362         """
363         if not self._use_threadlocal:
--> 364             return _ConnectionFairy._checkout(self)
365
366         try:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in _checkout(cls, pool, threadconns, fairy)
776     def _checkout(cls, pool, threadconns=None, fairy=None):
777         if not fairy:
--> 778             fairy = _ConnectionRecord.checkout(pool)
779
780             fairy._pool = pool

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in checkout(cls, pool)
493     @classmethod
494     def checkout(cls, pool):
--> 495         rec = pool._do_get()
496         try:
497             dbapi_connection = rec.get_connection()

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/impl.py in _do_get(self)
138             except:
139                 with util.safe_reraise():
--> 140                     self._dec_overflow()
141         else:
142             return self._do_get()

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py in __exit__(self, type_, value, traceback)
67             if not self.warn_only:
68                 compat.raise_(
---> 69                     exc_value, with_traceback=exc_tb,
70                 )
71         else:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
176
177         try:
--> 178             raise exception
179         finally:
180             # credit to

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/impl.py in _do_get(self)
135         if self._inc_overflow():
136             try:
--> 137                 return self._create_connection()
138             except:
139                 with util.safe_reraise():

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in _create_connection(self)
307         """Called by subclasses to create a new ConnectionRecord."""
308
--> 309         return _ConnectionRecord(self)
310
311     def _invalidate(self, connection, exception=None, _checkin=True):

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in __init__(self, pool, connect)
438         self.__pool = pool
439         if connect:
--> 440             self.__connect(first_connect_check=True)
441         self.finalize_callback = deque()
442

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in __connect(self, first_connect_check)
659         except Exception as e:
660             with util.safe_reraise():
--> 661                 pool.logger.debug("Error on connect(): %s", e)
662         else:
663             if first_connect_check:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py in __exit__(self, type_, value, traceback)
67             if not self.warn_only:
68                 compat.raise_(
---> 69                     exc_value, with_traceback=exc_tb,
70                 )
71         else:

/opt/conda/lib/python3.7/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
176
177         try:
--> 178             raise exception
179         finally:
180             # credit to

/opt/conda/lib/python3.7/site-packages/sqlalchemy/pool/base.py in __connect(self, first_connect_check)
654         try:
655             self.starttime = time.time()
--> 656             connection = pool._invoke_creator(self)
657             pool.logger.debug("Created new connection %r", connection)
658             self.connection = connection

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/strategies.py in connect(connection_record)
112                         if connection is not None:
113                             return connection
--> 114                 return dialect.connect(*cargs, **cparams)
115
116             creator = pop_kwarg("creator", connect)

/opt/conda/lib/python3.7/site-packages/sqlalchemy/engine/default.py in connect(self, *cargs, **cparams)
488     def connect(self, *cargs, **cparams):
489         # inherits the docstring from interfaces.Dialect.connect
--> 490         return self.dbapi.connect(*cargs, **cparams)
491
492     def create_connect_args(self, url):

InterfaceError: (pyodbc.InterfaceError) ('28000', "[28000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Login failed for user 'username'. (18456) (SQLDriverConnect)")
(Background on this error at: http://sqlalche.me/e/rvf5)

# Fixed code
def create_connect_args(self, url):
    opts = url.translate_connect_args(username="user")
    opts.update(url.query)

    keys = opts

    query = url.query

    connect_args = {}
    for param in ("ansi", "unicode_results", "autocommit"):
        if param in keys:
            connect_args[param] = util.asbool(keys.pop(param))

    if "odbc_connect" in keys:
        connectors = [util.unquote_plus(keys.pop("odbc_connect"))]
    else:

        def check_quote(token):
            if ";" in str(token):
                token = "{%s}" % token.replace("}", "}}")
            return token

        keys = dict((k, check_quote(v)) for k, v in keys.items())

        dsn_connection = "dsn" in keys or ("host" in keys and "database" not in keys)
        if dsn_connection:
            connectors = ["dsn=%s" % (keys.pop("host", "") or keys.pop("dsn", ""))]
        else:
            port = ""
            if "port" in keys and "port" not in query:
                port = ",%d" % int(keys.pop("port"))

            connectors = []
            driver = keys.pop("driver", self.pyodbc_driver_name)
            if driver is None and keys:
                # note if keys is empty, this is a totally blank URL
                util.warn(
                    "No driver name specified; "
                    "this is expected by PyODBC when using "
                    "DSN-less connections"
                )
            else:
                connectors.append("DRIVER={%s}" % driver)

            connectors.extend(
                [
                    "Server=%s%s" % (keys.pop("host", ""), port),
                    "Database=%s" % keys.pop("database", ""),
                ]
            )

        user = keys.pop("user", None)
        if user:
            connectors.append("UID=%s" % user)
            connectors.append("PWD=%s" % keys.pop("password", ""))
        else:
            connectors.append("Trusted_Connection=Yes")

        # if set to 'Yes', the ODBC layer will try to automagically
        # convert textual data from your database encoding to your
        # client encoding.  This should obviously be set to 'No' if
        # you query a cp1253 encoded database from a latin1 client...
        if "odbc_autotranslate" in keys:
            connectors.append("AutoTranslate=%s" % keys.pop("odbc_autotranslate"))

        connectors.extend(["%s=%s" % (k, v) for k, v in keys.items()])

    return [[";".join(connectors)], connect_args]