
    q-Ph@T                       d dl mZ d dlZd dlmZmZ d dlmZ d dlm	Z	m
Z
 d dlmZ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mZmZ d dlmZ d dlmZmZ d dl m!Z! d dl"m#Z# erPd dl$Z$d dlm%Z%m&Z& d dl'm(Z( d dl)Z*d dlm+Z+ e$j,        dk    rd dlm-Z- nd dl.m-Z- d dl/m0Z0 d dl1m2Z2 d dlm3Z3 d dl4m5Z5m6Z6m7Z7 h dZ8 G d d          Z9 G d d          Z:dS )    )annotationsN)	CoroutineSequence)suppress)	Parameter	signature)TYPE_CHECKINGAny)	functions)parse_version)
from_arrow)N_INFER_DEFAULT)DuplicateErrorModuleUpgradeRequiredErrorUnsuitableSQLError)ARROW_DRIVER_REGISTRY)ODBCCursorProxySurrealDBCursorProxy)dtype_from_cursor_description)
_run_async)IterableIterator)TracebackType)ArrowDriverProperties)      )Self
TextClause)
Selectable	DataFrame)ConnectionOrCursorCursor
SchemaDict>   USEDROPALTERCREATEDELETEINSERTUPDATEUPSERTVACUUMANALYZEREPLACEc                  "    e Zd ZdZddZdd
ZdS )CloseAfterFrameIterzDAllows cursor close to be deferred until the last batch is returned.framesr
   cursorr$   returnNonec               "    || _         || _        d S N)_iter_frames_cursor)selfr3   r4   s      \/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/polars/io/database/_executor.py__init__zCloseAfterFrameIter.__init__=   s    "    Iterator[DataFrame]c              #     K   | j         E d {V  t          | j        d          r| j                                         d S d S )Nclose)r9   hasattrr:   rA   r;   s    r<   __iter__zCloseAfterFrameIter.__iter__A   sY      $$$$$$$$4<)) 	!L     	! 	!r>   N)r3   r
   r4   r$   r5   r6   )r5   r?   )__name__
__module____qualname____doc__r=   rD    r>   r<   r2   r2   :   sB        NN   ! ! ! ! ! !r>   r2   c                  V   e Zd ZU dZdZded<   dKd	ZdLdZdMdZdNdZ	e
dOd            ZdPdZe
dQd            ZdRd$Ze
dSd)            ZdTd*ZdUd.ZdUd/ZdVd2Ze
dWd5            Ze
dWd6            Ze
dWd7            Ze
dWd8            ZdXd9ZdYd=ZdZdAZdBdCdDd[dGZddBdBedHd\dJZdBS )]ConnectionExecutorzIAbstraction for querying databases with user-supplied connection objects.Fboolcan_close_cursor
connectionr#   r5   r6   c                6   t          |t                    rdn?t          |          j                            dd          d                                         | _        | j        dk    rt          |          }|                     |          | _	        d | _
        d S )Narrow_odbc_proxy.   r   	surrealdb)client)
isinstancer   typerF   splitlowerdriver_namer   _normalise_cursorr4   result)r;   rN   s     r<   r=   zConnectionExecutor.__init__O   s     *o66Fj!!,223::1=CCEE 	
 {**-Z@@@J,,Z88r>   r   c                    | S r8   rI   rC   s    r<   	__enter__zConnectionExecutor.__enter__[   s    r>   exc_typetype[BaseException] | Noneexc_valBaseException | Noneexc_tbTracebackType | Nonec                ,   |                      | j                  r@ddlm} t	          | j        |          r#t          |                                            d S d S | j        r0t          | j        d          r| j        	                                 d S d S d S )Nr   )AsyncConnectionrA   )
_is_alchemy_asyncr4   sqlalchemy.ext.asynciore   rU   r   _close_async_cursorrM   rB   rA   )r;   r^   r`   rb   re   s        r<   __exit__zConnectionExecutor.__exit__^   s     !!$+.. 	 >>>>>>$+77 743355666667 7" 	 wt{G'D'D 	 K	  	  	  	 r>   strc                B    dt          |           j         d| j        dS )N<z module=>)rV   rE   rY   rC   s    r<   __repr__zConnectionExecutor.__repr__n   s'    E4::&EE0@EEEEr>   dfr"   schema_overridesr%   c                    | j         fd|                                D             x}r|                     |          } | S )z&Apply schema overrides to a DataFrame.c                    g | ]<\  }}|v 	||         k    t          j        |                              |          =S rI   )Fcolcast).0rt   dtypeexisting_schemas      r<   
<listcomp>z7ConnectionExecutor._apply_overrides.<locals>.<listcomp>u   sU     
 
 
Uo%%%?33G*G*G E#JJOOE""*G*G*Gr>   )schemaitemswith_columns)ro   rp   	cast_colsrx   s      @r<   _apply_overridesz#ConnectionExecutor._apply_overridesq   sb     )
 
 
 
.4466
 
 
 
9 	,
 ++B	r>   c                   K   | j         rdt          | j        d          rQddlm} t          |          5  | j                                         d {V  d d d            d S # 1 swxY w Y   d S d S d S )NrA   r   )AsyncContextNotStarted)rM   rB   r4   sqlalchemy.ext.asyncio.excr   r   rA   )r;   r   s     r<   rh   z&ConnectionExecutor._close_async_cursor}   s        	*WT['%B%B 	*IIIIII011 * *k'')))))))))* * * * * * * * * * * * * * * * * *	* 	* 	* 	*s    A!!A%(A%module_nameminimum_versionc           	     R   t          |           }t          t                    5  d}dD ]9}t          t	          ||d          x}t
                    rt          |          } n:|r*|t          |          k     rd|  d| }t          |          ddd           dS # 1 swxY w Y   dS )z<Check the module version against a minimum required version.N)__version__versionz)`read_database` queries require at least z	 version )
__import__r   AttributeErrorrU   getattrrj   r   r   )r   r   modmodule_versionversion_attrvermsgs          r<   _check_module_versionz(ConnectionExecutor._check_module_version   s    %%n%% 	6 	659N :  WS,%E%EEcsKK %23%7%7NE  6.=3Q3Q"Q"Qi+iiXgii0555	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6s   A+BB #B driver_propertiesr   
batch_size
int | Noneiter_batchesIterable[pa.RecordBatch]c             #     K   |d         }|r|)|d         } t          | j        |                      V  dS |d         r|gng }|d         }t          | j        |          }|s || E d{V  dS 	  || }	|	sdS |	V  )zGYield Arrow data as a generator of one or more RecordBatches or Tables.fetch_batchesN	fetch_allexact_batch_sizerepeat_batch_calls)r   r[   )
r;   r   r   r   r   fetch_methodsizer   fetchmany_arrowarrows
             r<   _fetch_arrowzConnectionExecutor._fetch_arrow   s       */: 	 }4,[9L4'$+|446666666#45G#HPJ<<bD!23G!H%dk=AAO%  *?D1111111111 +OT2E  KKK	 r>   r[   r$   
is_alchemyIterable[Sequence[Any]]c                   |                                  }|r,|s(t          |d         t          t          t          f          r|nd |D             S )zCFetch row data in a single call, returning the complete result set.r   c                ,    g | ]}t          |          S rI   tuplerv   rows     r<   ry   z5ConnectionExecutor._fetchall_rows.<locals>.<listcomp>   s    ---%**---r>   )fetchallrU   listr   dict)r[   r   rowss      r<   _fetchall_rowsz!ConnectionExecutor._fetchall_rows   s\        .#.'1$q'D%;N'O'O.DD-----	
r>   c             #     K   	 |                     |          }|sdS |s(t          |d         t          t          t          f          r|V  nd |D             V  W)zDFetch row data incrementally, yielding over the complete result set.Tr   c                ,    g | ]}t          |          S rI   r   r   s     r<   ry   z6ConnectionExecutor._fetchmany_rows.<locals>.<listcomp>   s    222cuSzz222r>   N)	fetchmanyrU   r   r   r   )r;   r[   r   r   r   s        r<   _fetchmany_rowsz"ConnectionExecutor._fetchmany_rows   sy      	3##J//D 3 3z$q'D%3FGG 3



22T222222	3r>   SchemaDict | Noneinfer_schema_length&DataFrame | Iterator[DataFrame] | Nonec                   ddl m 	 t          j                    D ]\  }}t	          j        d| d j                  r|d         x}r                      j        |           |r$|d         r|sd j         d}t          |           fd	 	                    |||
          D             }	|r|	nt          |	          c S n5# t          $ r(d}
t          fd|
D                       s Y dndww xY wdS )z5Return resultset data in Arrow format for frame init.r   r!   ^$r   r   zCannot set `iter_batches` for z- without also setting a non-zero `batch_size`c              3     K   | ]=}t          |          r                    |pi           nt          |           V  >dS ))rp   N)rU   r~   r   )rv   batchr"   rp   r;   s     r<   	<genexpr>z1ConnectionExecutor._from_arrow.<locals>.<genexpr>   su       	 	 " &eY77R--e6F6L"NNN'@PQQQ	 	 	 	 	 	r>   )r   r   )zdoes not support Apache Arrowz$Apache Arrow format is not supportedc              3  :   K   | ]}|t                    v V  d S r8   )rj   )rv   eerrs     r<   r   z1ConnectionExecutor._from_arrow.<locals>.<genexpr>   s-      BBqCHH}BBBBBBr>   N)polarsr"   r   r{   rematchrY   r   
ValueErrorr   next	Exceptionany)r;   r   r   rp   r   driverr   r   r   r3   arrow_not_supportedr"   r   s   `  `       @@r<   _from_arrowzConnectionExecutor._from_arrow   s    	%$$$$$	-B-H-J-J D D))8MMMM4+;<< D/0ABBs J2243CSIII# .)*<=.FP. t?O~~~(oo-	 	 	 	 	 	 &*%6%6-)5'1 &7 & &		 	 	F &2C66tF||CCC)DD,  	 	 	# BBBB.ABBBBB     	 ts   B;C
 C
 

C<C77C<c                  ddl m |r|sd}t          |          t          | j        x}t
                    x}rt          | j                  | _        	 t          | j        d          rQ| j        dk    x}r{t          | j        d          rd | j        j	        j
        D             }	nxt          | j        d          rd	 | j        j        j        D             }	nGd
| j        }t          |          t          | j        d          rd | j        j
        D             }	ng }	|                     |	pi           d |	D             fd|r|                     | j        ||          n|                     | j        |          gD             }
|r|
nt!          |
          	 |r|                                 S S 	 |r|                                 dS dS # |r|                                 w w xY w)z.Return resultset data row-wise for frame init.r   r!   zFCannot set `iter_batches` without also setting a non-zero `batch_size`r   
sqlalchemyr4   c                2    g | ]}|d          |dd         fS r   rR   NrI   rv   ds     r<   ry   z1ConnectionExecutor._from_rows.<locals>.<listcomp>  s5     ' ' './QqT1QRR5M' ' 'r>   	_metadatac                    g | ]}|d fS r8   rI   )rv   ks     r<   ry   z1ConnectionExecutor._from_rows.<locals>.<listcomp>  s    &U&U&UQ4y&U&U&Ur>   z0Unable to determine metadata from query result; descriptionc                2    g | ]}|d          |dd         fS r   rI   r   s     r<   ry   z1ConnectionExecutor._from_rows.<locals>.<listcomp>  s(    "R"R"RQAaD!ABB%="R"R"Rr>   )r   rp   c                    g | ]\  }}|S rI   rI   )rv   nm_s      r<   ry   z1ConnectionExecutor._from_rows.<locals>.<listcomp>  s    !>!>!>Q"!>!>!>r>   c              3  <   K   | ]} |pd d          V  d S )Nr   )datarz   rp   r   orientrI   )rv   r   r"   r   result_columnsrp   s     r<   r   z0ConnectionExecutor._from_rows.<locals>.<genexpr>  s^          I!-5)9,?$       r>   )r   r   )r   N)r   r"   r   rU   r[   r   r   rB   rY   r4   r   r   keys_inject_type_overridesr   r   r   rA   )r;   r   r   rp   r   r   original_resultis_asyncr   cursor_descr3   r"   r   s      ``      @@r<   
_from_rowszConnectionExecutor._from_rows   s    	%$$$$$ 	"
 	"X  S//!!T["@/)LLL8 	2$T[11DK-	(t{J// (@"&"2l"BC: %t{H55 .' '37;3E3Q' ' ' !k:: .&U&U$+:O:T&U&U&U`QUQ\``(oo-T[-88 %"R"R$+:Q"R"R"RKK"$K#'#>#> +&6&<" $? $ $  "?!>+!>!>!>       (W,, K'1'1 -    #11$+*1UUV  $ ".?vv4<<?  (%%''''(  (%%'''''( (x (%%''''(s   EG G3r   list[tuple[str, Any]]c                    t                      }|D ]U\  }}||v rd|d}t          |          | ||vrt          | j        |          }||||<   |                    |           V|S )a  
        Attempt basic dtype inference from a cursor description.

        Notes
        -----
        This is limited; the `type_code` description attr may contain almost anything,
        from strings or python types to driver-specific codes, classes, enums, etc.
        We currently only do the additional inference from string/python type values.
        (Further refinement will require per-driver module knowledge and lookups).
        zcolumn z2 appears more than once in the query/result cursor)setr   r   r4   add)r;   r   rp   
dupe_checkr   descr   rw   s           r<   r   z)ConnectionExecutor._inject_type_overrides2  s     UU
# 	 	HBZXXXX$S)))!b0@&@&@5dk4HH$+0$R(NN2r>   connr
   c                `    	 ddl m}m}m} t	          | |||f          S # t
          $ r Y dS w xY w)z2Check if the given connection is SQLALchemy async.r   )re   AsyncSessionasync_sessionmakerF)rg   re   r   r   rU   ImportError)r   re   r   r   s       r<   rf   z$ConnectionExecutor._is_alchemy_asyncN  su    		          d_lDV$WXXX 	 	 	55	s    
--c                    ddl m} t          | |          rdS 	 ddlm} t          | |          S # t
          $ r Y dS w xY w)z5Check if the given connection is a SQLAlchemy Engine.r   )EngineT)AsyncEngineF)sqlalchemy.enginer   rU   rg   r   r   )r   r   r   s      r<   _is_alchemy_enginez%ConnectionExecutor._is_alchemy_engine\  sv     	-,,,,,dF## 	4	::::::dK000 	 	 	55	s   0 
>>c                f    t          |           j                            dd          d         dk    S )zCCheck if the given connection is a SQLAlchemy object (of any kind).rQ   rR   r   r   )rV   rF   rW   )r   s    r<   _is_alchemy_objectz%ConnectionExecutor._is_alchemy_objectj  s-     Dzz$**32215EEr>   c                    ddl m} ddlm}m} t          | |||f          rdS 	 ddl m} t          | |          S # t          $ r Y dS w xY w)z=Check if the given connection is a SQLAlchemy Session object.r   )r   )SessionsessionmakerT)r   F)rg   r   sqlalchemy.ormr   r   rU   r   r   )r   r   r   r   r   s        r<   _is_alchemy_sessionz&ConnectionExecutor._is_alchemy_sessiono  s     	87777788888888d\7LABB 	4	AAAAAAd$6777 	 	 	55	s   ; 
A	A	c                $   | j         dk    r|                     |          r|S |j        j        dk    r2d| _         |j                                                                        S |j        j        dk    r	d| _         |S |                     |          rd| _        |                                S |S t          |d          r+t          |j        x}          r
 |            n|}d| _        |S t          |d          r|S d	|d
}t          |          )zCNormalise a connection object such that we have the query executor.r   zdatabricks-sql-python
databricksduckdb_engineduckdbTr4   executezUnrecognised connection type "z""; no 'execute' or 'cursor' method)rY   r   enginer   raw_connectionr4   r   rM   connectrB   callable	TypeError)r;   r   r4   r   s       r<   rZ   z$ConnectionExecutor._normalise_cursor  s)   |++''--   ;%)@@@'3D$;5577>>@@@['?::'/D$K,,T22  ,0D)<<>>)KT8$$ 	!)DK*?&!@!@LVVXXXfF$(D!MT9%% 	K]]]]nnr>   queryr   optionsc                8  K   |                      | j                  }|r| j                                        n| j        }|4 d{V }|rt          |d          s|j        } |j        |fi | d{V }|cddd          d{V  S # 1 d{V swxY w Y   dS )z5Execute a query using an async SQLAlchemy connection.Nr   )r   r4   beginrB   sessionr   )r;   r   r   
is_sessionr4   r   r[   s          r<   _sqlalchemy_async_executez,ConnectionExecutor._sqlalchemy_async_execute  sI     --dk::
(2C""$$$ 	 	 	 	 	 	 	T $'$	":": $|'4<9999999999F		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   /B		
BBstr | TextClause | Selectabledict[str, Any]9tuple[Any, dict[str, Any], str | TextClause | Selectable]c                   ddl m} ddlm} ddlm} d}d}t          | j        |          r6d|v r2d|vr.|                                }|	                    d          |d<   d}|
                    |          }|                     | j                  }	|	st          |t                    rt          | j        d          rl| j        j        }t          ||          rt          |          }t          |t                     r+t#          d	 |D                       st%          |          ||<   n t          |t                    r ||          }||	r| j        n| j        j        }|||fS )
z<Prepare a query for execution using a SQLAlchemy connection.r   )r   )textr   
parametersNparamsexec_driver_sqlc              3  N   K   | ] }t          |t          t          f          V  !d S r8   )rU   r   r   rv   ps     r<   r   z7ConnectionExecutor._sqlalchemy_setup.<locals>.<genexpr>  sA       4 412
1tUm,,4 4 4 4 4 4r>   )r   r   sqlalchemy.sqlr
  sqlalchemy.sql.elementsr   rU   r4   copypopgetrf   r   rB   r  rj   r   allr   r  r   )
r;   r   r   r   r
  r   	param_keycursor_executer  r   s
             r<   _sqlalchemy_setupz$ConnectionExecutor._sqlalchemy_setup  s    	+*****''''''666666 	t{G,,	!''''llnnG 'L 9 9GH IY''))$+66	 68,,	  %677	 
 "[8N%,, #E

&$'' 3 4 46<4 4 4 1 1 3 &+6]]	"s## 	 DKKE!2:S..@S  w--r>   NT)r   select_queries_onlydict[str, Any] | Noner  c                  |rtt          |t                    r_t          j        dt          j        dd|                    }|sdn|                    d          x}t          v r| d}t          |          pi |                     | j	                  r| 
                    |          \  }}n| j	        j        }	 t          |          j        }n# t          $ r i }Y nw xY wr+t          d |                                D                       r
 ||fi }	nfd|pD             }
 ||g|
R  }	|	|	d	u r| j	        n|	}	| j        d
k    r|	j	        }	|	| _        | S )z-Execute a query and reference the result set.z\w{3,}z/\*(.|[\r\n])*?\*/ r   z( statements are not valid 'read' queriesc              3  T   K   | ]#}|j         t          j        t          j        fv V  $d S r8   )kindr   KEYWORD_ONLYPOSITIONAL_OR_KEYWORDr  s     r<   r   z-ConnectionExecutor.execute.<locals>.<genexpr>  sH       
 
 Fy-y/NOO
 
 
 
 
 
r>   c              3  4   K   | ]}r|v |         V  d S r8   rI   )rv   or   s     r<   r   z-ConnectionExecutor.execute.<locals>.<genexpr>  s=       " " "KLPW<<
<<<<" "r>   NTr   )rU   rj   r   searchsubgroup_INVALID_QUERY_TYPESr   r   r4   r  r   r   r  r   r   valuesrY   r[   )r;   r   r   r  q
query_typer   r  r  r[   positional_optionss     `        r<   r   zConnectionExecutor.execute  s     	.:eS#9#9 	.	)RV,A2u%M%MNNA()9bbqwwqzz9
>RRR#MMM(----R""4;// 	1-1-C-CE7-S-S*NGUU![0N	~..9FF 	 	 	FFF	  		@# 
 
]]__
 
 
 
 
 		@ $^E55W55FF" " " "%+%6w" " " $^E?,>???F "(6T>>x'']Fs   >C C"!C")r   r   rp   r   DataFrame | Iterator[DataFrame]c               ,   | j         d}t          |          | j        }|o|x}rd| _        | j        | j        fD ]9} |||||          }	|	&|r d t          |	| j                   D             }	|	c S :d| j        d| j        }t          |          )	z
        Convert the result set to a DataFrame.

        Wherever possible we try to return arrow-native data directly; only
        fall back to initialising with row-level data if no other option.
        Nz.cannot return a frame before executing a queryF)r   r   rp   r   c              3     K   | ]}|V  d S r8   rI   )rv   ro   s     r<   r   z/ConnectionExecutor.to_polars.<locals>.<genexpr>'  s6              r>   )r4   zCurrently no support for z connection )	r[   RuntimeErrorrM   r   r   r2   rY   r4   NotImplementedError)
r;   r   r   rp   r   r   	can_closedefer_cursor_close
frame_initframes
             r<   	to_polarszConnectionExecutor.to_polars  s	    ;BCs###)	"."<9= 	*$)D! O
 	 	J J%)!1$7	  E  %  "5!#';# # #  E  ! X(8WWWW 	 "#&&&r>   )rN   r#   r5   r6   )r5   r   )r^   r_   r`   ra   rb   rc   r5   r6   )r5   rj   )ro   r"   rp   r%   r5   r"   )r5   r6   )r   rj   r   rj   r5   r6   )r   r   r   r   r   rL   r5   r   )r[   r$   r   rL   r5   r   )r[   r$   r   r   r   rL   r5   r   )
r   r   r   rL   rp   r   r   r   r5   r   )r   r   rp   r%   r5   r%   )r   r
   r5   rL   )r   r
   r5   r$   )r   r   r   r
   r5   r
   )r   r  r   r  r5   r  )r   r  r   r  r  rL   r5   r   )
r   rL   r   r   rp   r   r   r   r5   r,  )rE   rF   rG   rH   rM   __annotations__r=   r]   ri   rn   staticmethodr~   rh   r   r   r   r   r   r   r   rf   r   r   r   rZ   r  r  r   r   r5  rI   r>   r<   rK   rK   H   sw        SS #""""
  
  
  
            F F F F 	 	 	 \	* * * * 6 6 6 \6       2 
 
 
 \
3 3 3 3, , , ,\@( @( @( @(D       8    \    \ F F F \F    \   B   ). ). ). ).^ *.$(- - - - - -d #!%.2*9/' /' /' /' /' /' /' /'r>   rK   );
__future__r   r   collections.abcr   r   
contextlibr   inspectr   r   typingr	   r
   r   r   rs   polars._utils.variousr   polars.convertr   polars.datatypesr   polars.exceptionsr   r   r   "polars.io.database._arrow_registryr   "polars.io.database._cursor_proxiesr   r   polars.io.database._inferencer   polars.io.database._utilsr   sysr   r   typesr   pyarrowpar   version_infor   typing_extensionsr  r   sqlalchemy.sql.expressionr    r"   polars._typingr#   r$   r%   r'  r2   rK   rI   r>   r<   <module>rM     s   " " " " " " 				 / / / / / / / /       ( ( ( ( ( ( ( ( % % % % % % % % ! ! ! ! ! ! / / / / / / % % % % % % , , , , , ,         
 E D D D D D T T T T T T T T G G G G G G 0 0 0 0 0 0 FJJJ22222222######HHHHHH
7""******222222444444      EEEEEEEEEE   ! ! ! ! ! ! ! !k' k' k' k' k' k' k' k' k' k'r>   