B
    \;%                 @   sp  d Z ddlZddl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 ddlmZ ddlmZ ddlmZ ddlmZ yddlmZ W n ek
r   dZY nX G dd dejZG dd deZG dd deZG dd deZG dd de	ZG dd deZG dd  d e
Z G d!d" d"eZ!e!Z"dS )#a  
.. dialect:: postgresql+pg8000
    :name: pg8000
    :dbapi: pg8000
    :connectstring: postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]
    :url: https://pythonhosted.org/pg8000/


.. _pg8000_unicode:

Unicode
-------

pg8000 will encode / decode string values between it and the server using the
PostgreSQL ``client_encoding`` parameter; by default this is the value in
the ``postgresql.conf`` file, which often defaults to ``SQL_ASCII``.
Typically, this can be changed to ``utf-8``, as a more useful default::

    #client_encoding = sql_ascii # actually, defaults to database
                                 # encoding
    client_encoding = utf8

The ``client_encoding`` can be overridden for a session by executing the SQL:

SET CLIENT_ENCODING TO 'utf8';

SQLAlchemy will execute this SQL on all new connections based on the value
passed to :func:`.create_engine` using the ``client_encoding`` parameter::

    engine = create_engine(
        "postgresql+pg8000://user:pass@host/dbname", client_encoding='utf8')


.. _pg8000_isolation_level:

pg8000 Transaction Isolation Level
-------------------------------------

The pg8000 dialect offers the same isolation level settings as that
of the :ref:`psycopg2 <psycopg2_isolation_level>` dialect:

* ``READ COMMITTED``
* ``READ UNCOMMITTED``
* ``REPEATABLE READ``
* ``SERIALIZABLE``
* ``AUTOCOMMIT``

.. versionadded:: 0.9.5 support for AUTOCOMMIT isolation level when using
   pg8000.

.. seealso::

    :ref:`postgresql_isolation_level`

    :ref:`psycopg2_isolation_level`


    N   )_DECIMAL_TYPES)_FLOAT_TYPES)
_INT_TYPES)
PGCompiler)	PGDialect)PGExecutionContext)PGIdentifierPreparer)UUID)JSON   )exc)
processors)types)util)quoted_namec               @   s   e Zd Zdd ZdS )
_PGNumericc             C   sv   | j rB|tkrttj| jS |tks.|tkr2d S t	
d| n0|tkrNd S |tks^|tkrdtjS t	
d| d S )NzUnknown PG numeric type: %d)Z	asdecimalr   r   Zto_decimal_processor_factorydecimalZDecimalZ_effective_decimal_return_scaler   r   r   ZInvalidRequestErrorZto_float)selfdialectcoltype r   Dlib/python3.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyresult_processor[   s    z_PGNumeric.result_processorN)__name__
__module____qualname__r   r   r   r   r   r   Z   s   r   c               @   s   e Zd Zdd ZdS )_PGNumericNoBindc             C   s   d S )Nr   )r   r   r   r   r   bind_processoru   s    z_PGNumericNoBind.bind_processorN)r   r   r   r   r   r   r   r   r   t   s   r   c                   s   e Zd Z fddZ  ZS )_PGJSONc                s$   |j dkrd S tt| ||S d S )N)r   
   r   )_dbapi_versionsuperr   r   )r   r   r   )	__class__r   r   r   z   s    
z_PGJSON.result_processor)r   r   r   r   __classcell__r   r   )r#   r   r   y   s   r   c               @   s   e Zd Zdd Zdd ZdS )_PGUUIDc             C   s   | j sdd }|S d S )Nc             S   s   | d k	rt | } | S )N)_python_UUID)valuer   r   r   process   s    z'_PGUUID.bind_processor.<locals>.process)as_uuid)r   r   r(   r   r   r   r      s    z_PGUUID.bind_processorc             C   s   | j sdd }|S d S )Nc             S   s   | d k	rt | } | S )N)str)r'   r   r   r   r(      s    z)_PGUUID.result_processor.<locals>.process)r)   )r   r   r   r(   r   r   r   r      s    z_PGUUID.result_processorN)r   r   r   r   r   r   r   r   r   r%      s   
r%   c               @   s   e Zd ZdS )PGExecutionContext_pg8000N)r   r   r   r   r   r   r   r+      s   r+   c               @   s   e Zd Zdd Zdd ZdS )PGCompiler_pg8000c             K   s$   | j |jf|d | j |jf| S )Nz %% )r(   leftright)r   Zbinaryoperatorkwr   r   r   visit_mod_binary   s    z"PGCompiler_pg8000.visit_mod_binaryc             C   s   d|krt d |ddS )Nz%%z^The SQLAlchemy postgresql dialect now automatically escapes '%' in text() expressions to '%%'.%)r   warnreplace)r   textr   r   r   post_process_text   s    z#PGCompiler_pg8000.post_process_textN)r   r   r   r1   r6   r   r   r   r   r,      s   r,   c               @   s   e Zd Zdd ZdS )PGIdentifierPreparer_pg8000c             C   s   | | j| j}| ddS )Nr2   z%%)r4   Zescape_quoteZescape_to_quote)r   r'   r   r   r   _escape_identifier   s    z.PGIdentifierPreparer_pg8000._escape_identifierN)r   r   r   r8   r   r   r   r   r7      s   r7   c                   s   e Zd ZdZdZdZdZdZeZ	e
ZeZdZeejejeejeeeejeeeiZd#ddZ fdd	Zejd
d Ze dd Z!dd Z"dd Z#dd Z$dd Z%dd Z&dd Z'd$ddZ(d%ddZ)dd  Z*d!d" Z+  Z,S )&PGDialect_pg8000pg8000TformatZuse_encodingNc             K   s   t j| f| || _d S )N)r   __init__client_encoding)r   r=   kwargsr   r   r   r<      s    zPGDialect_pg8000.__init__c                s    | j dk| _tt| | d S )N)r   	      )r!   supports_sane_multi_rowcountr"   r9   
initialize)r   
connection)r#   r   r   rB      s    zPGDialect_pg8000.initializec             C   s8   | j r0t| j dr0tdd td| j jD S dS d S )N__version__c             S   s   g | ]}t |qS r   )int).0xr   r   r   
<listcomp>   s   z3PGDialect_pg8000._dbapi_version.<locals>.<listcomp>z(\d+)(?:[-\.]?|$))c   rI   rI   )dbapihasattrtuplerefindallrD   )r   r   r   r   r!      s    zPGDialect_pg8000._dbapi_versionc             C   s   t dS )Nr:   )
__import__)clsr   r   r   rJ      s    zPGDialect_pg8000.dbapic             C   s8   |j dd}d|kr$t|d |d< ||j g |fS )Nuser)ZusernameZport)Ztranslate_connect_argsrE   updateZquery)r   ZurlZoptsr   r   r   create_connect_args   s
    z$PGDialect_pg8000.create_connect_argsc             C   s   dt |kS )Nzconnection is closed)r*   )r   erC   cursorr   r   r   is_disconnect   s    zPGDialect_pg8000.is_disconnectc             C   s   | dd}t|dr|j}|dkr,d|_nX|| jkrfd|_| }|d|  |d |  nt	d	|| j
d
| jf d S )N_ rC   Z
AUTOCOMMITTFz=SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL %sCOMMITzZInvalid value '%s' for isolation_level. Valid isolation levels for %s are %s or AUTOCOMMITz, )r4   rK   rC   Z
autocommitZ_isolation_lookuprU   executecloser   ZArgumentErrornamejoin)r   rC   levelrU   r   r   r   set_isolation_level   s     



z$PGDialect_pg8000.set_isolation_levelc             C   s@   t |dr|j}| }|d| d  |d |  d S )NrC   zSET CLIENT_ENCODING TO ''rY   )rK   rC   rU   rZ   r[   )r   rC   r=   rU   r   r   r   set_client_encoding	  s    

z$PGDialect_pg8000.set_client_encodingc             C   s   |j d|df d S )Nr    )rC   Z	tpc_begin)r   rC   xidr   r   r   do_begin_twophase  s    z"PGDialect_pg8000.do_begin_twophasec             C   s   |j   d S )N)rC   Ztpc_prepare)r   rC   rc   r   r   r   do_prepare_twophase  s    z$PGDialect_pg8000.do_prepare_twophaseFc             C   s   |j d|df d S )Nr   rb   )rC   Ztpc_rollback)r   rC   rc   is_preparedrecoverr   r   r   do_rollback_twophase  s    z%PGDialect_pg8000.do_rollback_twophasec             C   s   |j d|df d S )Nr   rb   )rC   Z
tpc_commit)r   rC   rc   rf   rg   r   r   r   do_commit_twophase  s    z#PGDialect_pg8000.do_commit_twophasec             C   s   dd |j  D S )Nc             S   s   g | ]}|d  qS )r   r   )rF   rowr   r   r   rH   $  s    z8PGDialect_pg8000.do_recover_twophase.<locals>.<listcomp>)rC   Ztpc_recover)r   rC   r   r   r   do_recover_twophase#  s    z$PGDialect_pg8000.do_recover_twophasec                sz   g  dd }  | jd k	r6fdd}  | jd k	rVfdd}  | t dkrr fdd}|S d S d S )Nc             S   s   | j tj | j t< d S )N)Zpy_typesr   Z	text_typer   )connr   r   r   
on_connect)  s    z/PGDialect_pg8000.on_connect.<locals>.on_connectc                s     |  j d S )N)ra   r=   )rl   )r   r   r   rm   0  s    c                s     |  j d S )N)r_   isolation_level)rl   )r   r   r   rm   7  s    r   c                s   x D ]}||  qW d S )Nr   )rl   fn)fnsr   r   rm   >  s    
)appendr=   rn   len)r   rm   r   )rp   r   r   rm   &  s    




zPGDialect_pg8000.on_connect)N)TF)TF)-r   r   r   ZdriverZsupports_unicode_statementsZsupports_unicode_bindsZdefault_paramstylerA   r+   Zexecution_ctx_clsr,   Zstatement_compilerr7   ZpreparerZdescription_encodingr   Zupdate_copyr   ZcolspecssqltypesNumericr   ZFloatr   r   r   r
   r%   r<   rB   Zmemoized_propertyr!   classmethodrJ   rS   rV   r_   ra   rd   re   rh   ri   rk   rm   r$   r   r   )r#   r   r9      s<   




r9   )#__doc__r   rM   baser   r   r   r   r   r   r	   r
   Zjsonr   rb   r   r   r   rs   r   Zsql.elementsr   Zuuidr&   ImportErrorrt   r   r   r   r%   r+   r,   r7   r9   r   r   r   r   r   <module>@   s<   
 