o
    i%                     @   sn  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 zddlmZ W n eyq   dZY nw 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/

.. note::

    The pg8000 dialect is **not tested as part of SQLAlchemy's continuous
    integration** and may have unresolved issues.  The recommended PostgreSQL
    dialect is psycopg2.

.. _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:`_sa.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                   @      e Zd Zdd ZdS )
_PGNumericc                 C   sp   | j r |tv rttj| jS |tv s|tv rd S t	
d| |tv r&d S |tv s.|tv r1tjS t	
d| )NzUnknown PG numeric type: %d)	asdecimalr   r   to_decimal_processor_factorydecimalDecimal_effective_decimal_return_scaler   r   r   InvalidRequestErrorto_floatselfdialectcoltype r   `/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyresult_processor`   s"   z_PGNumeric.result_processorN)__name__
__module____qualname__r!   r   r   r   r    r   _       r   c                   @   r   )_PGNumericNoBindc                 C   s   d S Nr   )r   r   r   r   r    bind_processorz   s   z_PGNumericNoBind.bind_processorN)r"   r#   r$   r(   r   r   r   r    r&   y   r%   r&   c                       s   e Zd Z fddZ  ZS )_PGJSONc                    s    |j dkrd S tt| ||S )N)r   
   r   )_dbapi_versionsuperr)   r!   r   	__class__r   r    r!      s   
z_PGJSON.result_processor)r"   r#   r$   r!   __classcell__r   r   r-   r    r)   ~   s    r)   c                   @      e Zd Zdd Zdd ZdS )_PGUUIDc                 C   s   | j s	dd }|S d S )Nc                 S      | d urt | } | S r'   )_python_UUIDvaluer   r   r    process      z'_PGUUID.bind_processor.<locals>.processas_uuid)r   r   r6   r   r   r    r(         z_PGUUID.bind_processorc                 C   s   | j s	dd }|S d S )Nc                 S   r2   r'   strr4   r   r   r    r6      r7   z)_PGUUID.result_processor.<locals>.processr8   )r   r   r   r6   r   r   r    r!      r:   z_PGUUID.result_processorN)r"   r#   r$   r(   r!   r   r   r   r    r1      s    
r1   c                   @   s   e Zd ZdS )PGExecutionContext_pg8000N)r"   r#   r$   r   r   r   r    r=      s    r=   c                   @   r0   )PGCompiler_pg8000c                 K   s,   | j |jfi |d | j |jfi | S )Nz %% )r6   leftright)r   binaryoperatorkwr   r   r    visit_mod_binary   s   z"PGCompiler_pg8000.visit_mod_binaryc                 C   s   d|v r	t d |ddS )N%%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$   rD   rJ   r   r   r   r    r>      s    r>   c                   @   r   )PGIdentifierPreparer_pg8000c                 C   s   | | j| j}| ddS )NrF   rE   )rH   escape_quoteescape_to_quote)r   r5   r   r   r    _escape_identifier   s   z.PGIdentifierPreparer_pg8000._escape_identifierN)r"   r#   r$   rN   r   r   r   r    rK      r%   rK   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formatuse_encodingNc                 K   s   t j| fi | || _d S r'   )r   __init__client_encoding)r   rT   kwargsr   r   r    rS      s   
zPGDialect_pg8000.__init__c                    s    | j dk| _tt| | d S )N)r   	      )r+   supports_sane_multi_rowcountr,   rO   
initializer   
connectionr-   r   r    rY      s   zPGDialect_pg8000.initializec                 C   s4   | j rt| j drtdd td| j j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   ra   ra   )dbapihasattrtuplerefindallr\   r   r   r   r    r+      s   	zPGDialect_pg8000._dbapi_versionc                 C   s   t dS )NrP   )
__import__)clsr   r   r    rb      s   zPGDialect_pg8000.dbapic                 C   s8   |j dd}d|v rt|d |d< ||j g |fS )Nuser)usernameport)translate_connect_argsr]   updatequery)r   urloptsr   r   r    create_connect_args   s
   z$PGDialect_pg8000.create_connect_argsc                 C   s   dt |v S )Nzconnection is closedr;   )r   er[   cursorr   r   r    is_disconnect   s   zPGDialect_pg8000.is_disconnectc                 C   s   | dd}t|dr|j}|dkrd|_d S || jv r5d|_| }|d|  |d |  d S t	d	|| j
d
| jf )N_ r[   
AUTOCOMMITTFz=SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL %sCOMMITzZInvalid value '%s' for isolation_level. Valid isolation levels for %s are %s or AUTOCOMMITz, )rH   rc   r[   
autocommit_isolation_lookuprt   executecloser   ArgumentErrornamejoin)r   r[   levelrt   r   r   r    set_isolation_level   s(   



z$PGDialect_pg8000.set_isolation_levelc                 C   s@   t |dr|j}| }|d| d  |d |  d S )Nr[   zSET CLIENT_ENCODING TO ''ry   )rc   r[   rt   r|   r}   )r   r[   rT   rt   r   r   r    set_client_encoding  s   

z$PGDialect_pg8000.set_client_encodingc                 C      |j d|df d S Nr    )r[   	tpc_beginr   r[   xidr   r   r    do_begin_twophase     z"PGDialect_pg8000.do_begin_twophasec                 C   s   |j   d S r'   )r[   tpc_preparer   r   r   r    do_prepare_twophase  s   z$PGDialect_pg8000.do_prepare_twophaseFc                 C   r   r   )r[   tpc_rollbackr   r[   r   is_preparedrecoverr   r   r    do_rollback_twophase     z%PGDialect_pg8000.do_rollback_twophasec                 C   r   r   )r[   
tpc_commitr   r   r   r    do_commit_twophase#  r   z#PGDialect_pg8000.do_commit_twophasec                 C   s   dd |j  D S )Nc                 S   s   g | ]}|d  qS )r   r   )r^   rowr   r   r    r`   )  s    z8PGDialect_pg8000.do_recover_twophase.<locals>.<listcomp>)r[   tpc_recoverrZ   r   r   r    do_recover_twophase(  s   z$PGDialect_pg8000.do_recover_twophasec                    sv   g  dd }  | jd urfdd}  | jd ur+fdd}  | t dkr9 fdd}|S d S )Nc                 S   s   | j tj | j t< d S r'   )py_typesr   	text_typer   connr   r   r    
on_connect.  r   z/PGDialect_pg8000.on_connect.<locals>.on_connectc                         |  j d S r'   )r   rT   r   rg   r   r    r   5     c                    r   r'   )r   isolation_levelr   rg   r   r    r   <  r   r   c                    s    D ]}||  qd S r'   r   )r   fn)fnsr   r    r   C  s   
)appendrT   r   len)r   r   r   )r   r   r    r   +  s   




zPGDialect_pg8000.on_connectr'   )TF)-r"   r#   r$   driversupports_unicode_statementssupports_unicode_bindsdefault_paramstylerX   r=   execution_ctx_clsr>   statement_compilerrK   preparerdescription_encodingr   update_copyr   colspecssqltypesNumericr&   Floatr   r   r)   r
   r1   rS   rY   memoized_propertyr+   classmethodrb   rr   ru   r   r   r   r   r   r   r   r   r/   r   r   r-   r    rO      sJ    





rO   )#__doc__r   re   baser   r   r   r   r   r   r	   r
   jsonr   r   r   r   r   r   r   sql.elementsr   uuidr3   ImportErrorr   r   r&   r)   r1   r=   r>   rK   rO   r   r   r   r   r    <module>   s@   ? 