
    j                        d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z	 d	d
l
mZ ddlmZ ddlmZ er$ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddZ G d de      ZeZy)a  

.. dialect:: mysql+pymysql
    :name: PyMySQL
    :dbapi: pymysql
    :connectstring: mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
    :url: https://pymysql.readthedocs.io/

Unicode
-------

Please see :ref:`mysql_unicode` for current recommendations on unicode
handling.

.. _pymysql_ssl:

SSL Connections
------------------

The PyMySQL DBAPI accepts the same SSL arguments as that of MySQLdb,
described at :ref:`mysqldb_ssl`.   See that section for additional examples.

If the server uses an automatically-generated certificate that is self-signed
or does not match the host name (as seen from the client), it may also be
necessary to indicate ``ssl_check_hostname=false`` in PyMySQL::

    connection_uri = (
        "mysql+pymysql://scott:tiger@192.168.0.134/test"
        "?ssl_ca=/home/gord/client-ssl/ca.pem"
        "&ssl_cert=/home/gord/client-ssl/client-cert.pem"
        "&ssl_key=/home/gord/client-ssl/client-key.pem"
        "&ssl_check_hostname=false"
    )

MySQL-Python Compatibility
--------------------------

The pymysql DBAPI is a pure Python port of the MySQL-python (MySQLdb) driver,
and targets 100% compatibility.   Most behavioral notes for MySQL-python apply
to the pymysql driver as well.

    )annotations)Any)Dict)Optional)Type)TYPE_CHECKING)Union   )MySQLDialect_mysqldb   )langhelpers)Literal)ConnectArgsType)DBAPIConnection)DBAPICursor)DBAPIModule)PoolProxiedConnection)URLc                    t        j                  | j                        }	 |j                  d   }|dk(  xr  |j                   xs |j                  d   duS # t
        $ r Y yw xY w)ax  Given a Connection class like pymysql.Connection, aiomysql.Connection,
    asyncmy.Connection, inspect the ping() method and determine if it
    has a "reconnect" parameter that either defaults to True, or is positional.

    a return value of True here means that when we call ``connection.ping()``,
    we **must** pass `reconnect=False`.  a return value of False means that
    we should call ``connection.ping()`` with **no arguments**.

    This routine originates from issue #10492 for pymysql, however arg
    signature mismatches in aiomysql/asyncmy tracked by issue #13306
    necessitated a more open ended function.

    r
   	reconnectr   F)r   get_callable_argspecpingargsdefaults
IndexError)connection_clsinspreconnect_args      H/tmp/pip-target-jj7clzyk/lib/python/sqlalchemy/dialects/mysql/pymysql.py _connection_ping_reconnects_truer    J   sq     ++N,?,?@D
		! + 
>q!1!>	
  s   A 	A#"A#c                       e Zd ZdZdZdZej                  dd       Ze	dd       Z
ej                  dd       ZddZ	 d	 	 	 	 	 d fdZ	 	 	 	 	 	 	 	 d fd	Zdd
Z xZS )MySQLDialect_pymysqlpymysqlTNc                |    	 t        d      j                  }|j                  | _        y# t        t
        f$ r Y yw xY w)Nzpymysql.cursorsTF)
__import__cursorsSSCursor	_sscursorImportErrorAttributeError)selfr&   s     r   supports_server_side_cursorsz1MySQLDialect_pymysql.supports_server_side_cursorsi   s?    	 !23;;G$--DN^, 		s   &) ;;c                    t        d      S )Nr#   )r%   )clss    r   import_dbapiz!MySQLDialect_pymysql.import_dbapir   s    )$$    c                    	 t        d      j                  j                  }t        |      S # t        t
        f$ r Y yw xY w)a4  determine if pymysql has deprecated, changed the default of,
        or removed the 'reconnect' argument of connection.ping().

        See #10492 and
        https://github.com/PyMySQL/mysqlclient/discussions/651#discussioncomment-7308971
        for background.

        Revised as part of #13306

        zpymysql.connectionsT)r%   connections
Connectionr    r)   r*   )r+   r3   s     r   _send_false_to_pingz(MySQLDialect_pymysql._send_false_to_pingv   sG    	@#%k**  4J?? ^, 		s   , >>c                `    | j                   r|j                  d       y|j                          y)NFT)r4   r   )r+   dbapi_connections     r   do_pingzMySQLDialect_pymysql.do_ping   s/    ##!!%(  !!#r0   c                B    |t        d      }t        | 	  ||      S )Nuser)username)_translate_args)dictsupercreate_connect_args)r+   urlr;   	__class__s      r   r>   z(MySQLDialect_pymysql.create_connect_args   s1     ""F3Ow* + 
 	
r0   c                    t         |   |||      ryt        || j                  j                        r#t        |      j                         }d|v xs d|v S y)NTzalready closedzconnection was killedF)r=   is_disconnect
isinstanceloaded_dbapiErrorstrlower)r+   e
connectioncursorstr_er@   s        r   rB   z"MySQLDialect_pymysql.is_disconnect   s[     7 J74,,223FLLNE E)M-D-M r0   c                x    t        |j                  d   t              r|j                  d   }|j                  d   S )Nr   )rC   r   	Exception)r+   	exceptions     r   _extract_error_codez(MySQLDialect_pymysql._extract_error_code   s2    innQ'3!q)I~~a  r0   )returnbool)rP   r   )r6   r   rP   zLiteral[True])N)r?   r   r;   zOptional[Dict[str, Any]]rP   r   )rH   zDBAPIModule.ErrorrI   z7Optional[Union[PoolProxiedConnection, DBAPIConnection]]rJ   zOptional[DBAPICursor]rP   rQ   )rN   BaseExceptionrP   r   )__name__
__module____qualname__driversupports_statement_cachedescription_encodingr   memoized_propertyr,   classmethodr/   r4   r7   r>   rB   rO   __classcell__)r@   s   @r   r"   r"   c   s    F#"" # % % ""@ #@* EI

)A
	
 L &	
 
 !r0   r"   N)r   z	Type[Any]rP   rQ   )__doc__
__future__r   typingr   r   r   r   r   r	   mysqldbr   utilr   util.typingr   engine.interfacesr   r   r   r   r   
engine.urlr   r    r"   dialect r0   r   <module>rf      s\   )V #        )  "4400:!
2M!/ M!` r0   