ó
¿b›]c           @   sé  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 Wn e k
 r+d Z n Xd e j f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e	 f d „  ƒ  YZ d e f d „  ƒ  YZ  d e
 f d  „  ƒ  YZ! d! e f d" „  ƒ  YZ" e" Z# d S(#   sÔ  
.. 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:`.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`


iÿÿÿÿNi   (   t   _DECIMAL_TYPES(   t   _FLOAT_TYPES(   t
   _INT_TYPES(   t
   PGCompiler(   t	   PGDialect(   t   PGExecutionContext(   t   PGIdentifierPreparer(   t   UUID(   t   JSONi   (   t   exc(   t
   processors(   t   types(   t   util(   t   quoted_namet
   _PGNumericc           B   s   e  Z d  „  Z RS(   c         C   s£   |  j  r] | t k r+ t j t j |  j ƒ S| t k sC | t k rG d  St
 j d | ƒ ‚ nB | t k rm d  S| t k s… | t k rŒ t j St
 j d | ƒ ‚ d  S(   Ns   Unknown PG numeric type: %d(   t	   asdecimalR   R
   t   to_decimal_processor_factoryt   decimalt   Decimalt   _effective_decimal_return_scaleR    R   t   NoneR	   t   InvalidRequestErrort   to_float(   t   selft   dialectt   coltype(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   result_processor`   s    	(   t   __name__t
   __module__R   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR   _   s   t   _PGNumericNoBindc           B   s   e  Z d  „  Z RS(   c         C   s   d  S(   N(   R   (   R   R   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   bind_processorz   s    (   R   R   R   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR   y   s   t   _PGJSONc           B   s   e  Z d  „  Z RS(   c         C   s0   | j  d k r d  St t |  ƒ j | | ƒ Sd  S(   Ni   i
   (   i   i
   i   (   t   _dbapi_versionR   t   superR   R   (   R   R   R   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR      s    (   R   R   R   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR   ~   s   t   _PGUUIDc           B   s   e  Z d  „  Z d „  Z RS(   c         C   s   |  j  s d „  } | Sd  S(   Nc         S   s   |  d  k	 r t |  ƒ }  n  |  S(   N(   R   t   _python_UUID(   t   value(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   processŠ   s    (   t   as_uuid(   R   R   R%   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR   ‡   s    		c         C   s   |  j  s d „  } | Sd  S(   Nc         S   s   |  d  k	 r t |  ƒ }  n  |  S(   N(   R   t   str(   R$   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR%   ”   s    (   R&   (   R   R   R   R%   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR   ‘   s    		(   R   R   R   R   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR"   †   s   	
t   PGExecutionContext_pg8000c           B   s   e  Z RS(    (   R   R   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR(   œ   s   t   PGCompiler_pg8000c           B   s   e  Z d  „  Z d „  Z RS(   c         K   s*   |  j  | j |  d |  j  | j |  S(   Ns    %% (   R%   t   leftt   right(   R   t   binaryt   operatort   kw(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   visit_mod_binary¡   s    c         C   s,   d | k r t  j d ƒ n  | j d d ƒ S(   Ns   %%s^   The SQLAlchemy postgresql dialect now automatically escapes '%' in text() expressions to '%%'.t   %(   R   t   warnt   replace(   R   t   text(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   post_process_text¨   s    
(   R   R   R/   R4   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR)       s   	t   PGIdentifierPreparer_pg8000c           B   s   e  Z d  „  Z RS(   c         C   s(   | j  |  j |  j ƒ } | j  d d ƒ S(   NR0   s   %%(   R2   t   escape_quotet   escape_to_quote(   R   R$   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   _escape_identifier³   s    (   R   R   R8   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR5   ²   s   t   PGDialect_pg8000c           B   s  e  Z d  Z e Z e Z d Z e Z e Z	 e
 Z e Z d Z e j e j i e e j 6e e j 6e e 6e e j 6e e 6ƒ Z d d „ Z d „  Z e j d „  ƒ Z  e! d „  ƒ Z" d „  Z# d „  Z$ d	 „  Z% d
 „  Z& d „  Z' d „  Z( e e) d „ Z* e e) d „ Z+ d „  Z, d „  Z- RS(   t   pg8000t   formatt   use_encodingc         K   s   t  j |  |  | |  _ d  S(   N(   R   t   __init__t   client_encoding(   R   R>   t   kwargs(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR=   Ñ   s    c         C   s,   |  j  d k |  _ t t |  ƒ j | ƒ d  S(   Ni   i	   i   (   i   i	   i   (   R    t   supports_sane_multi_rowcountR!   R9   t
   initialize(   R   t
   connection(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyRA   Õ   s    c         C   sX   |  j  rP t |  j  d ƒ rP t g  t j d |  j  j ƒ D] } t | ƒ ^ q7 ƒ Sd Sd  S(   Nt   __version__s   (\d+)(?:[-\.]?|$)ic   (   ic   ic   ic   (   t   dbapit   hasattrt   tuplet   ret   findallRC   t   int(   R   t   x(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR    Ù   s    )c         C   s
   t  d ƒ S(   NR:   (   t
   __import__(   t   cls(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyRD   ç   s    c         C   sO   | j  d d ƒ } d | k r5 t | d ƒ | d <n  | j | j ƒ g  | f S(   Nt   usernamet   usert   port(   t   translate_connect_argsRI   t   updatet   query(   R   t   urlt   opts(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   create_connect_argsë   s
    c         C   s   d t  | ƒ k S(   Ns   connection is closed(   R'   (   R   t   eRB   t   cursor(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   is_disconnectò   s    c         C   sÃ   | j  d d ƒ } t | d ƒ r- | j } n  | d k rE t | _ nz | |  j k r” t | _ | j ƒ  } | j d | ƒ | j d ƒ | j	 ƒ  n+ t
 j d | |  j d j |  j ƒ f ƒ ‚ d  S(	   Nt   _t    RB   t
   AUTOCOMMITs=   SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL %st   COMMITsZ   Invalid value '%s' for isolation_level. Valid isolation levels for %s are %s or AUTOCOMMITs   , (   R2   RE   RB   t   Truet
   autocommitt   _isolation_lookupt   FalseRW   t   executet   closeR	   t   ArgumentErrort   namet   join(   R   RB   t   levelRW   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   set_isolation_levelõ   s     	c         C   sW   t  | d ƒ r | j } n  | j ƒ  } | j d | d ƒ | j d ƒ | j ƒ  d  S(   NRB   s   SET CLIENT_ENCODING TO 't   'R\   (   RE   RB   RW   Ra   Rb   (   R   RB   R>   RW   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   set_client_encoding  s    c         C   s   | j  j d | d f ƒ d  S(   Ni    t    (   RB   t	   tpc_begin(   R   RB   t   xid(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   do_begin_twophase  s    c         C   s   | j  j ƒ  d  S(   N(   RB   t   tpc_prepare(   R   RB   Rl   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   do_prepare_twophase  s    c         C   s   | j  j d | d f ƒ d  S(   Ni    Rj   (   RB   t   tpc_rollback(   R   RB   Rl   t   is_preparedt   recover(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   do_rollback_twophase  s    c         C   s   | j  j d | d f ƒ d  S(   Ni    Rj   (   RB   t
   tpc_commit(   R   RB   Rl   Rq   Rr   (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   do_commit_twophase#  s    c         C   s$   g  | j  j ƒ  D] } | d ^ q S(   Ni   (   RB   t   tpc_recover(   R   RB   t   row(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   do_recover_twophase(  s    c            s¥   g  ‰  d „  } ˆ  j  | ƒ ˆ j d  k	 rJ ‡ f d †  } ˆ  j  | ƒ n  ˆ j d  k	 rx ‡ f d †  } ˆ  j  | ƒ n  t ˆ  ƒ d k r ‡  f d †  } | Sd  Sd  S(   Nc         S   s   |  j  t j |  j  t <d  S(   N(   t   py_typesR   t	   text_typeR   (   t   conn(    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt
   on_connect.  s    c            s   ˆ  j  |  ˆ  j ƒ d  S(   N(   Ri   R>   (   R{   (   R   (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR|   5  s    c            s   ˆ  j  |  ˆ  j ƒ d  S(   N(   Rg   t   isolation_level(   R{   (   R   (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR|   <  s    i    c            s   x ˆ  D] } | |  ƒ q Wd  S(   N(    (   R{   t   fn(   t   fns(    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR|   C  s    (   t   appendR>   R   R}   t   len(   R   R|   (    (   R   R   sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR|   +  s    	N(.   R   R   t   driverR]   t   supports_unicode_statementst   supports_unicode_bindst   default_paramstyleR@   R(   t   execution_ctx_clsR)   t   statement_compilerR5   t   preparert   description_encodingR   t   update_copyR   t   colspecsR   t   sqltypest   NumericR   t   FloatR   R   R"   R   R   R=   RA   t   memoized_propertyR    t   classmethodRD   RU   RX   Rg   Ri   Rm   Ro   R`   Rs   Ru   Rx   R|   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyR9   ¸   s>   


					
			($   t   __doc__R   RG   t   baseR    R   R   R   R   R   R   R   t   jsonR   Rj   R	   R
   R   RŒ   R   t   sql.elementsR   t   uuidR#   t   ImportErrorR   R   R   R   R   R"   R(   R)   R5   R9   R   (    (    (    sD   lib/python2.7/site-packages/sqlalchemy/dialects/postgresql/pg8000.pyt   <module>E   s:   
”