
    MhH                   @   S r SSKJr  SSKJrJr  SSKJrJr  SSK	J
r
J	r	Jr  SSKJr  SSKrSSKJrJrJrJrJrJr  SSKrSSKrSS	KJr  SS
KJr  SSKJr  SSKJ r J!r!  SSK"J#r#  SSK$J%r%  SSK&J'r'J(r(  SSK)J*r*J+r+  SSK,J-r-  SSK.J/r/  SSK0J1r1J2r2  SSK3J4r4  SSK5J6r6  SSK7J8s  J9r:  SSK7J;r;  SSK<J=r=  SSK>J?r?  \(       a*  SSK@JArAJBrB  SSKCJDrD  SSKEJFrFJGrG  SSKHJIrIJJrJJKrKJLrLJMrM  SSK.JNrN  S rO SO   SPS jjrPS  rQ  SQ     SRS# jjrR     SS     STS$ jjrSSSSS"S%.       SUS& jjrTSVS' jrU\       SW             SXS( jj5       rV\       SW             SYS) jj5       rVSSS!SSS\R                  4                 SZS* jjrV\       SW             S[S+ jj5       rX\       SW             S\S, jj5       rXSS!SSSS\R                  4               S]S- jjrX\        S^           S_S. jj5       rY\        S^           S`S/ jj5       rYSS!SSSS\R                  S4             SaS0 jjrY        Sb                   ScS1 jjrZSVSdS2 jjr[\[r\  Se     SfS4 jjr] " S5 S6\65      r^ " S7 S3\6\5      r_ " S8 S95      r` " S: S;\`5      raSgS< jrb " S= S>\_5      rc " S? S@\_5      rdSASBSCSDSESFSCSG.reShSH jrfShSI jrg " SJ SK\^5      rh " SL SM\_5      ri    Si       SjSN jjrjg)kz|
Collection of query wrappers / abstractions to both facilitate data
retrieval and to reduce dependency on DB-specific API.
    )annotations)ABCabstractmethod)	ExitStackcontextmanager)datedatetimetime)partialN)TYPE_CHECKINGAnyCallableLiteralcastoverload)using_pyarrow_string_dtype)libimport_optional_dependency)AbstractMethodErrorDatabaseError)find_stack_level)check_dtype_backend)is_dict_likeis_list_like)
ArrowDtypeDatetimeTZDtype)isna)
get_option)	DataFrameSeries)ArrowExtensionArray)PandasObject)maybe_make_list)convert_object_array)to_datetime)IteratorMapping)Table)Select
TextClause)DateTimeErrorChoicesDtypeArgDtypeBackend
IndexLabelSelf)Indexc                P    U SL d  U b  U SL a  / n U $ [        U S5      (       d  U /n U $ )z3Process parse_dates argument for read_sql functionsTF__iter__)hasattr)parse_datess    ?/var/www/html/env/lib/python3.13/site-packages/pandas/io/sql.py_process_parse_dates_argumentr7   ^   sA     dk1[E5I  [*--"m    c                4   [        U[        5      (       a<  UR                  SS 5      =(       d    SnUS:X  a   [        U 40 UD6$ [        U 4SU0UD6$ Uch  [        U R                  R                  [        R                  5      (       d3  [        U R                  R                  [        R                  5      (       a  SnUS;   a  [        U SX!S9$ [        U R                  [        5      (       a
  [        U SS9$ [        U SX!S	9$ ! [        [
        4 a    U s $ f = f)
Nerrorsignores)Ddhmr<   msusnscoerce)r:   unitutcTrF   )r:   formatrF   )
isinstancedictpopr&   	TypeError
ValueError
issubclassdtypetypenpfloatingintegerr   )colrF   rH   errors       r6   _handle_date_columnrV   i   s     &$
 '-jj4&@&LHH"31&11 37u777 >syy~~r{{33#)).."**55F@@s8&JJ		?33 s--s8FLL' z* 
s   D DDc           	        [        U5      n[        U R                  5       5       HL  u  nu  p4[        UR                  [
        5      (       d  X1;   d  M.   X   nU R                  U[        XES95        MN     U $ ! [        [        4 a    Sn N3f = f)zn
Force non-datetime columns to be read as such.
Supports both string formatted and integer timestamp columns.
NrH   )
r7   	enumerateitemsrI   rO   r   KeyErrorrL   isetitemrV   )
data_framer5   icol_namedf_colfmts         r6   _parse_date_columnsrb      s    
 0<K
 "+:+;+;+=!>HfllO448O!+ #6v#JK "? 	 i( s   A77BBTnumpyc                   [         R                  " U 5      n[        [        UR                  5      S UUS9nUS:X  aq  [        S5      n/ nU H\  nUR                  USS9n	UR                  S:X  a  U	R                  UR                  5       5      n	UR                  [        U	5      5        M^     UnU(       aA  [        [        [        [        [        [!        U5      5      5      U5      5      5      n
Xl        U
$ [        US9$ )N)rO   coerce_floatdtype_backendpyarrowT)from_pandasstring)columns)r   to_object_array_tuplesr%   listTr   arrayrO   r   ri   appendr"   r    rJ   ziprangelenrj   )datarj   re   rf   contentarraysparesult_arraysarrpa_arraydfs              r6   _convert_arrays_to_dataframer{      s     ((.G!WYY!#	F 	!'	2Cxxx6HyyH$ $==5  !4X!>?  tCU3w<%8 96BCD
	))r8   c                    [        XX65      nU(       a  UR                  U5      n[        Xt5      nUb  UR                  U5      nU$ z5Wrap result set of a SQLAlchemy query in a DataFrame.)r{   astyperb   	set_index)rs   rj   	index_colre   r5   rO   rf   frames           r6   _wrap_resultr      sD     )TEU#3E	*Lr8   )r   r5   rO   rf   c               t    U(       a  U R                  U5      n [        X5      n Ub  U R                  U5      n U $ r}   )r~   rb   r   )rz   r   r5   rO   rf   s        r6   _wrap_result_adbcr      s8     YYu	R	-B\\)$Ir8   c                8   [         R                  " S[        [        5       S9  [	        SSS9nUb6  [        U[        UR                  R                  45      (       a  [        S5      e[        USS	9 nUR                  X5      sSSS5        $ ! , (       d  f       g= f)
an  
Execute the given SQL query using the provided connection object.

Parameters
----------
sql : string
    SQL query to be executed.
con : SQLAlchemy connection or sqlite3 connection
    If a DBAPI2 object, only sqlite3 is supported.
params : list or tuple, optional, default: None
    List of parameters to pass to execute method.

Returns
-------
Results Iterable
zP`pandas.io.sql.execute` is deprecated and will be removed in the future version.
stacklevel
sqlalchemyr;   r:   Nz+pandas.io.sql.execute requires a connectionT)need_transaction)warningswarnFutureWarningr   r   rI   strengineEnginerL   pandasSQL_builderexecute)sqlconparamsr   
pandas_sqls        r6   r   r      s    " MM	1#%	 ,LJJ*S3
8I8I8P8P2Q"R"REFF	3	6*!!#. 
7	6	6s   0B
Bc	                    g N 	
table_namer   schemar   re   r5   rj   	chunksizerf   s	            r6   read_sql_tabler          r8   c	                    g r   r   r   s	            r6   r   r     r   r8   c	                R   [        U5        U[        R                  L a  SnU[        R                  Ld   e[        XSS9 n	U	R	                  U 5      (       d  [        SU  S35      eU	R                  U UUUUUUS9n
SSS5        W
b  U
$ [        SU  S3U5      e! , (       d  f       N#= f)aP	  
Read SQL database table into a DataFrame.

Given a table name and a SQLAlchemy connectable, returns a DataFrame.
This function does not support DBAPI connections.

Parameters
----------
table_name : str
    Name of SQL table in database.
con : SQLAlchemy connectable or str
    A database URI could be provided as str.
    SQLite DBAPI connection mode not supported.
schema : str, default None
    Name of SQL schema in database to query (if database flavor
    supports this). Uses default schema if None (default).
index_col : str or list of str, optional, default: None
    Column(s) to set as index(MultiIndex).
coerce_float : bool, default True
    Attempts to convert values of non-string, non-numeric objects (like
    decimal.Decimal) to floating point. Can result in loss of Precision.
parse_dates : list or dict, default None
    - List of column names to parse as dates.
    - Dict of ``{column_name: format string}`` where format string is
      strftime compatible in case of parsing string times or is one of
      (D, s, ns, ms, us) in case of parsing integer timestamps.
    - Dict of ``{column_name: arg dict}``, where the arg dict corresponds
      to the keyword arguments of :func:`pandas.to_datetime`
      Especially useful with databases without native Datetime support,
      such as SQLite.
columns : list, default None
    List of column names to select from SQL table.
chunksize : int, default None
    If specified, returns an iterator where `chunksize` is the number of
    rows to include in each chunk.
dtype_backend : {'numpy_nullable', 'pyarrow'}, default 'numpy_nullable'
    Back-end data type applied to the resultant :class:`DataFrame`
    (still experimental). Behaviour is as follows:

    * ``"numpy_nullable"``: returns nullable-dtype-backed :class:`DataFrame`
      (default).
    * ``"pyarrow"``: returns pyarrow-backed nullable :class:`ArrowDtype`
      DataFrame.

    .. versionadded:: 2.0

Returns
-------
DataFrame or Iterator[DataFrame]
    A SQL table is returned as two-dimensional data structure with labeled
    axes.

See Also
--------
read_sql_query : Read SQL query into a DataFrame.
read_sql : Read SQL query or database table into a DataFrame.

Notes
-----
Any datetime values with time zone information will be converted to UTC.

Examples
--------
>>> pd.read_sql_table('table_name', 'postgres:///db_name')  # doctest:+SKIP
rc   Tr   r   zTable z
 not foundr   re   r5   rj   r   rf   N)r   r   
no_defaultr   	has_tablerM   
read_table)r   r   r   r   re   r5   rj   r   rf   r   tables              r6   r   r   .  s    Z &&...	3	E##J//vj\<==%%%#' & 
	 
F 6*Z8#>># 
F	Es    ;B
B&c	                    g r   r   	r   r   r   re   r   r5   r   rO   rf   s	            r6   read_sql_queryr     r   r8   c	                    g r   r   r   s	            r6   r   r     r   r8   c	                    [        U5        U[        R                  L a  SnU[        R                  Ld   e[        U5       n	U	R	                  U UUUUUUUS9sSSS5        $ ! , (       d  f       g= f)a  
Read SQL query into a DataFrame.

Returns a DataFrame corresponding to the result set of the query
string. Optionally provide an `index_col` parameter to use one of the
columns as the index, otherwise default integer index will be used.

Parameters
----------
sql : str SQL query or SQLAlchemy Selectable (select or text object)
    SQL query to be executed.
con : SQLAlchemy connectable, str, or sqlite3 connection
    Using SQLAlchemy makes it possible to use any DB supported by that
    library. If a DBAPI2 object, only sqlite3 is supported.
index_col : str or list of str, optional, default: None
    Column(s) to set as index(MultiIndex).
coerce_float : bool, default True
    Attempts to convert values of non-string, non-numeric objects (like
    decimal.Decimal) to floating point. Useful for SQL result sets.
params : list, tuple or mapping, optional, default: None
    List of parameters to pass to execute method.  The syntax used
    to pass parameters is database driver dependent. Check your
    database driver documentation for which of the five syntax styles,
    described in PEP 249's paramstyle, is supported.
    Eg. for psycopg2, uses %(name)s so use params={'name' : 'value'}.
parse_dates : list or dict, default: None
    - List of column names to parse as dates.
    - Dict of ``{column_name: format string}`` where format string is
      strftime compatible in case of parsing string times, or is one of
      (D, s, ns, ms, us) in case of parsing integer timestamps.
    - Dict of ``{column_name: arg dict}``, where the arg dict corresponds
      to the keyword arguments of :func:`pandas.to_datetime`
      Especially useful with databases without native Datetime support,
      such as SQLite.
chunksize : int, default None
    If specified, return an iterator where `chunksize` is the number of
    rows to include in each chunk.
dtype : Type name or dict of columns
    Data type for data or columns. E.g. np.float64 or
    {'a': np.float64, 'b': np.int32, 'c': 'Int64'}.

    .. versionadded:: 1.3.0
dtype_backend : {'numpy_nullable', 'pyarrow'}, default 'numpy_nullable'
    Back-end data type applied to the resultant :class:`DataFrame`
    (still experimental). Behaviour is as follows:

    * ``"numpy_nullable"``: returns nullable-dtype-backed :class:`DataFrame`
      (default).
    * ``"pyarrow"``: returns pyarrow-backed nullable :class:`ArrowDtype`
      DataFrame.

    .. versionadded:: 2.0

Returns
-------
DataFrame or Iterator[DataFrame]

See Also
--------
read_sql_table : Read SQL database table into a DataFrame.
read_sql : Read SQL query or database table into a DataFrame.

Notes
-----
Any datetime values with time zone information parsed via the `parse_dates`
parameter will be converted to UTC.

Examples
--------
>>> from sqlalchemy import create_engine  # doctest: +SKIP
>>> engine = create_engine("sqlite:///database.db")  # doctest: +SKIP
>>> with engine.connect() as conn, conn.begin():  # doctest: +SKIP
...     data = pd.read_sql_table("data", conn)  # doctest: +SKIP
rc   )r   r   re   r5   r   rO   rf   N)r   r   r   r   
read_query)
r   r   r   re   r   r5   r   rO   rf   r   s
             r6   r   r     sq    l &&...	3	:$$%#' % 	
 
 		s   A!!
A/c
                    g r   r   
r   r   r   re   r   r5   rj   r   rf   rO   s
             r6   read_sqlr          r8   c
                    g r   r   r   s
             r6   r   r   *  r   r8   c
                   [        U5        U[        R                  L a  SnU[        R                  Ld   e[        U5       n
[	        U
[
        5      (       a  U
R                  U UUUUUUU	S9sSSS5        $  U
R                  U 5      nU(       a  U
R                  U UUUUUUS9sSSS5        $ U
R                  U UUUUUUU	S9sSSS5        $ ! [         a    Sn NRf = f! , (       d  f       g= f)a  
Read SQL query or database table into a DataFrame.

This function is a convenience wrapper around ``read_sql_table`` and
``read_sql_query`` (for backward compatibility). It will delegate
to the specific function depending on the provided input. A SQL query
will be routed to ``read_sql_query``, while a database table name will
be routed to ``read_sql_table``. Note that the delegated function might
have more specific notes about their functionality not listed here.

Parameters
----------
sql : str or SQLAlchemy Selectable (select or text object)
    SQL query to be executed or a table name.
con : ADBC Connection, SQLAlchemy connectable, str, or sqlite3 connection
    ADBC provides high performance I/O with native type support, where available.
    Using SQLAlchemy makes it possible to use any DB supported by that
    library. If a DBAPI2 object, only sqlite3 is supported. The user is responsible
    for engine disposal and connection closure for the ADBC connection and
    SQLAlchemy connectable; str connections are closed automatically. See
    `here <https://docs.sqlalchemy.org/en/20/core/connections.html>`_.
index_col : str or list of str, optional, default: None
    Column(s) to set as index(MultiIndex).
coerce_float : bool, default True
    Attempts to convert values of non-string, non-numeric objects (like
    decimal.Decimal) to floating point, useful for SQL result sets.
params : list, tuple or dict, optional, default: None
    List of parameters to pass to execute method.  The syntax used
    to pass parameters is database driver dependent. Check your
    database driver documentation for which of the five syntax styles,
    described in PEP 249's paramstyle, is supported.
    Eg. for psycopg2, uses %(name)s so use params={'name' : 'value'}.
parse_dates : list or dict, default: None
    - List of column names to parse as dates.
    - Dict of ``{column_name: format string}`` where format string is
      strftime compatible in case of parsing string times, or is one of
      (D, s, ns, ms, us) in case of parsing integer timestamps.
    - Dict of ``{column_name: arg dict}``, where the arg dict corresponds
      to the keyword arguments of :func:`pandas.to_datetime`
      Especially useful with databases without native Datetime support,
      such as SQLite.
columns : list, default: None
    List of column names to select from SQL table (only used when reading
    a table).
chunksize : int, default None
    If specified, return an iterator where `chunksize` is the
    number of rows to include in each chunk.
dtype_backend : {'numpy_nullable', 'pyarrow'}, default 'numpy_nullable'
    Back-end data type applied to the resultant :class:`DataFrame`
    (still experimental). Behaviour is as follows:

    * ``"numpy_nullable"``: returns nullable-dtype-backed :class:`DataFrame`
      (default).
    * ``"pyarrow"``: returns pyarrow-backed nullable :class:`ArrowDtype`
      DataFrame.

    .. versionadded:: 2.0
dtype : Type name or dict of columns
    Data type for data or columns. E.g. np.float64 or
    {'a': np.float64, 'b': np.int32, 'c': 'Int64'}.
    The argument is ignored if a table is passed instead of a query.

    .. versionadded:: 2.0.0

Returns
-------
DataFrame or Iterator[DataFrame]

See Also
--------
read_sql_table : Read SQL database table into a DataFrame.
read_sql_query : Read SQL query into a DataFrame.

Examples
--------
Read data from SQL via either a SQL query or a SQL tablename.
When using a SQLite database only SQL queries are accepted,
providing only the SQL tablename will result in an error.

>>> from sqlite3 import connect
>>> conn = connect(':memory:')
>>> df = pd.DataFrame(data=[[0, '10/11/12'], [1, '12/11/10']],
...                   columns=['int_column', 'date_column'])
>>> df.to_sql(name='test_data', con=conn)
2

>>> pd.read_sql('SELECT int_column, date_column FROM test_data', conn)
   int_column date_column
0           0    10/11/12
1           1    12/11/10

>>> pd.read_sql('test_data', 'postgres:///db_name')  # doctest:+SKIP

Apply date parsing to columns through the ``parse_dates`` argument
The ``parse_dates`` argument calls ``pd.to_datetime`` on the provided columns.
Custom argument values for applying ``pd.to_datetime`` on a column are specified
via a dictionary format:

>>> pd.read_sql('SELECT int_column, date_column FROM test_data',
...             conn,
...             parse_dates={"date_column": {"format": "%d/%m/%y"}})
   int_column date_column
0           0  2012-11-10
1           1  2010-11-12

.. versionadded:: 2.2.0

   pandas now supports reading via ADBC drivers

>>> from adbc_driver_postgresql import dbapi  # doctest:+SKIP
>>> with dbapi.connect('postgres:///db_name') as conn:  # doctest:+SKIP
...     pd.read_sql('SELECT int_column FROM test_data', conn)
   int_column
0           0
1           1
rc   )r   r   re   r5   r   rf   rO   NFr   )
r   r   r   r   rI   SQLiteDatabaser   r   	Exceptionr   )r   r   r   re   r   r5   rj   r   rf   rO   r   _is_table_names               r6   r   r   :  s   B &&...	3	:j.11((#)'#+ ) 	 
 		#'11#6N
 ((#)'#+ ) ) 
 	< ((#)'#+ ) 	= 
 	  	#"N	# 
 	s6   +C7CC-CCCCC
C,c                <   US;  a  [        SU S35      e[        U [        5      (       a  U R                  5       n O [        U [        5      (       d  [        S5      e[        X#SS9 nUR                  " U U4UUUUUUU	U
S.UD6sSSS5        $ ! , (       d  f       g= f)	a  
Write records stored in a DataFrame to a SQL database.

Parameters
----------
frame : DataFrame, Series
name : str
    Name of SQL table.
con : ADBC Connection, SQLAlchemy connectable, str, or sqlite3 connection
    or sqlite3 DBAPI2 connection
    ADBC provides high performance I/O with native type support, where available.
    Using SQLAlchemy makes it possible to use any DB supported by that
    library.
    If a DBAPI2 object, only sqlite3 is supported.
schema : str, optional
    Name of SQL schema in database to write to (if database flavor
    supports this). If None, use default schema (default).
if_exists : {'fail', 'replace', 'append'}, default 'fail'
    - fail: If table exists, do nothing.
    - replace: If table exists, drop it, recreate it, and insert data.
    - append: If table exists, insert data. Create if does not exist.
index : bool, default True
    Write DataFrame index as a column.
index_label : str or sequence, optional
    Column label for index column(s). If None is given (default) and
    `index` is True, then the index names are used.
    A sequence should be given if the DataFrame uses MultiIndex.
chunksize : int, optional
    Specify the number of rows in each batch to be written at a time.
    By default, all rows will be written at once.
dtype : dict or scalar, optional
    Specifying the datatype for columns. If a dictionary is used, the
    keys should be the column names and the values should be the
    SQLAlchemy types or strings for the sqlite3 fallback mode. If a
    scalar is provided, it will be applied to all columns.
method : {None, 'multi', callable}, optional
    Controls the SQL insertion clause used:

    - None : Uses standard SQL ``INSERT`` clause (one per row).
    - ``'multi'``: Pass multiple values in a single ``INSERT`` clause.
    - callable with signature ``(pd_table, conn, keys, data_iter) -> int | None``.

    Details and a sample callable implementation can be found in the
    section :ref:`insert method <io.sql.method>`.
engine : {'auto', 'sqlalchemy'}, default 'auto'
    SQL engine library to use. If 'auto', then the option
    ``io.sql.engine`` is used. The default ``io.sql.engine``
    behavior is 'sqlalchemy'

    .. versionadded:: 1.3.0

**engine_kwargs
    Any additional kwargs are passed to the engine.

Returns
-------
None or int
    Number of rows affected by to_sql. None is returned if the callable
    passed into ``method`` does not return an integer number of rows.

    .. versionadded:: 1.4.0

Notes
-----
The returned rows affected is the sum of the ``rowcount`` attribute of ``sqlite3.Cursor``
or SQLAlchemy connectable. If using ADBC the returned rows are the result
of ``Cursor.adbc_ingest``. The returned value may not reflect the exact number of written
rows as stipulated in the
`sqlite3 <https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.rowcount>`__ or
`SQLAlchemy <https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.BaseCursorResult.rowcount>`__
)failreplacero   '' is not valid for if_existsz9'frame' argument should be either a Series or a DataFrameTr   )	if_existsindexindex_labelr   r   rO   methodr   N)rM   rI   r!   to_framer    NotImplementedErrorr   to_sql)r   namer   r   r   r   r   r   rO   r   r   engine_kwargsr   s                r6   r   r     s    j 551YK'CDEE%   y))!G
 	
 
3	E  
  #
 
 
F	E	Es   &B
Bc                l    [        XS9 nUR                  U 5      sSSS5        $ ! , (       d  f       g= f)a<  
Check if DataBase has named table.

Parameters
----------
table_name: string
    Name of SQL table.
con: ADBC Connection, SQLAlchemy connectable, str, or sqlite3 connection
    ADBC provides high performance I/O with native type support, where available.
    Using SQLAlchemy makes it possible to use any DB supported by that
    library.
    If a DBAPI2 object, only sqlite3 is supported.
schema : string, default None
    Name of SQL schema in database to write to (if database flavor supports
    this). If None, use default schema (default).

Returns
-------
boolean
r   N)r   r   )r   r   r   r   s       r6   r   r   Y  s(    * 
3	.*##J/ 
/	.	.   %
3	PandasSQLc                   SSK n[        XR                  5      (       d  U c  [        U 5      $ [	        SSS9n[        U [
        5      (       a  Uc  [        S5      eUb7  [        U [
        UR                  R                  45      (       a  [        XU5      $ [	        SSS9nU(       a%  [        XR                  5      (       a  [        U 5      $ [        R                  " S[        [        5       S	9  [        U 5      $ )
z
Convenience function to return the correct PandasSQL subclass based on the
provided parameters.  Also creates a sqlalchemy connection and transaction
if necessary.
r   Nr   r;   r   z.Using URI string without sqlalchemy installed.zadbc_driver_manager.dbapizpandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.r   )sqlite3rI   
Connectionr   r   r   ImportErrorr   ConnectableSQLDatabaseADBCDatabaser   r   UserWarningr   )r   r   r   r   r   adbcs         r6   r   r   u  s     #))**ckc""+LJJ#s
 2JKK*S3
8I8I8U8U2V"W"W3(899%&A(SD
300C  MM	D 	#% #r8   c                  0   \ rS rSrSr        S           SS jjrS rSS jrSS jrSS jr	SS	 jr
SS
 jrSS jr  S     SS jjr   S       SS jjr     S          S!S jjrS rS rS r  S"   S#S jjrS$S jrS rSrg)%SQLTablei  z
For mapping Pandas tables to SQL tables.
Uses fact that table is reflected by SQLAlchemy to
do better type conversions.
Also holds various flags needed to avoid having to
pass them between functions all the time.
Nc                   Xl         X l        X`l        X0l        U R	                  XG5      U l        Xl        XPl        Xl        Xl	        Ub  U R                  5       U l        O5U R                  R                  U R                   U R                  5      U l        U R                  c  [        SU S35      e[        U R                   5      (       d  [        S5      eg )NzCould not init table 'r   zEmpty table name specified)r   pd_sqlprefixr   _index_namer   r   r   keysrO   _create_table_setupr   	get_tablerM   rr   )selfr   pandas_sql_enginer   r   r   r   r   r   r   rO   s              r6   __init__SQLTable.__init__  s     	'
%%e9
"	
113DJ ..tyy$++FDJ::5dV1=>>499~~9:: r8   c                b    U R                   R                  U R                  U R                  5      $ r   )r   r   r   r   r   s    r6   existsSQLTable.exists  s!    {{$$TYY<<r8   c                    SSK Jn  [        U" U R                  5      R	                  U R
                  R                  5      5      $ )Nr   )CreateTable)sqlalchemy.schemar   r   r   compiler   r   )r   r   s     r6   
sql_schemaSQLTable.sql_schema  s,    1;tzz*224;;??CDDr8   c                .   U R                   R                  U R                  R                  5      U l         U R                  R	                  5          U R                   R                  U R                  R                  S9  S S S 5        g ! , (       d  f       g = f)Nbind)r   to_metadatar   metarun_transactioncreater   r   s    r6   _execute_createSQLTable._execute_create  s[    ZZ++DKK,<,<=
[[((*JJ4;;??3 +**s   .B
Bc                   U R                  5       (       a  U R                  S:X  a  [        SU R                   S35      eU R                  S:X  aA  U R                  R                  U R                  U R                  5        U R                  5         g U R                  S:X  a  g [        SU R                   S35      eU R                  5         g )Nr   Table '' already exists.r   ro   r   r   )r   r   rM   r   r   
drop_tabler   r   r   s    r6   r   SQLTable.create  s    ;;==~~' 7499+5F!GHH~~*&&tyy$++>$$&8+ 1T^^$44P!QRR  "r8   c           	         U Vs/ s H  n[        [        X$5      5      PM     nnUR                  U R                  R	                  5       U5      nUR
                  $ s  snf )z
Execute SQL statement inserting data

Parameters
----------
conn : sqlalchemy.engine.Engine or sqlalchemy.engine.Connection
keys : list of str
   Column names
data_iter : generator of list
   Each item contains a list of values to be inserted
)rJ   rp   r   r   insertrowcount)r   connr   	data_iterrowrs   results          r6   _execute_insertSQLTable._execute_insert  sM     1::	S^$	:djj//148 ;s   Ac           	         SSK Jn  U Vs/ s H  n[        [        X%5      5      PM     nnU" U R                  5      R                  U5      nUR                  U5      nUR                  $ s  snf )z
Alternative to _execute_insert for DBs support multi-value INSERT.

Note: multi-value insert is usually faster for analytics DBs
and tables containing a few columns
but performance degrades quickly with increase of columns.

r   )r   )r   r   rJ   rp   r   valuesr   r   )	r   r   r   r   r   r   rs   stmtr   s	            r6   _execute_insert_multiSQLTable._execute_insert_multi  sZ     	&09:	S^$	:djj!((.d# ;s   A)c                   U R                   bF  U R                  R                  5       nU R                   UR                   l         UR	                  SS9  OU R                  n[        [        [        UR                  5      5      n[        U5      nS /U-  n[        UR                  5       5       GH  u  nu  pxUR                  R                  S:X  a  [        UR                   ["        5      (       a  SS Kn	U	R&                  R)                  UR                  R*                  5      (       a  UR                   R-                  [.        S9n
GO&[0        R2                  " 5          [0        R4                  " S[6        S9  [8        R:                  " UR<                  R?                  5       [.        S9n
S S S 5        OUR                   R?                  5       n
OUR                  R                  S	:X  ai  UR                   n[        U["        5      (       a#  UR-                  [8        R                  " S
5      S9nURA                  S5      RC                  [.        5      n
OUR                   RC                  [.        5      n
[        W
[8        RD                  5      (       d   [G        U
5      5       eURH                  (       a  [K        U
5      nS X'   XU'   GM     X54$ ! [
         a  n[        SU 35      UeS nAff = f! , (       d  f       N= f)NTinplacez!duplicate name in index/columns: Mr   )rO   r;   )categoryr@   zm8[ns]i8)&r   r   copynamesreset_indexrM   rl   mapr   rj   rr   rY   rZ   rO   kindrI   _valuesr"   rg   typesis_datepyarrow_dtypeto_numpyobjectr   catch_warningsfilterwarningsr   rQ   asarraydtto_pydatetimeviewr~   ndarrayrP   _can_hold_nar   )r   temperrcolumn_namesncols	data_listr^   _serrv   r>   valsmasks                r6   insert_dataSQLTable.insert_data  s1   ::!::??$D#zzDJJU   . ::DCT\\23L! (,fun	$TZZ\2KAxyy~~$ckk+>??(xx''		(?(?@@KK00v0>%446$33H}U "

366+?+?+A PA 76
 113A3&{{d$788==rxx/A=BDIIdO**62KK&&v.a,,5d1g5,AwaL? 3B &&Y  U #DSE!JKQTTU( 76s%   K AK(
K%K  K%(
K6	c                b  ^^ Uc  U R                   nO=US:X  a  U R                  nO*[        U5      (       a  [        X 5      nO[	        SU 35      eU R                  5       u  pE[        U R                  5      nUS:X  a  gUc  UnOUS:X  a  [	        S5      eXa-  S-   nS nU R                  R                  5        n	[        U5       HM  n
X-  m[        U
S-   U-  U5      mTT:  a    O0[        UU4S jU 5       6 nU" XU5      nUc  MB  Uc  UnMI  X-  nMO     S S S 5        U$ ! , (       d  f       U$ = f)NmultizInvalid parameter `method`: r   z%chunksize argument should be non-zero   c              3  ,   >#    U  H	  oTT v   M     g 7fr   r   ).0rx   end_istart_is     r6   	<genexpr>"SQLTable.insert.<locals>.<genexpr>^  s     "K#wu#5s   )r   r  callabler   rM   r'  rr   r   r   r   rq   minrp   )r   r   r   exec_insertr   r"  nrowschunkstotal_insertedr   r^   
chunk_iternum_insertedr.  r/  s                @@r6   r   SQLTable.insert:  sA    >..Kw44Kf!&/K;F8DEE**,DJJA:I!^DEE$)[[((*d6]-QUi/7e# "K"KL
*4zB+%-)5&6 # +  +* s   8A
DD
D.c              #  ~  #    SnU    UR                  U5      n	U	(       d  U(       d  [        R                  " / XES9v   OcSn[        XXW5      U l        U R                  XgS9  U R                  b$  U R                  R                  U R                  SS9  U R                  v   M  SSS5        g! , (       d  f       g= f7f)z,Return generator through chunked result set.FTrj   re   r5   rf   Nr  )	fetchmanyr    from_recordsr{   r   _harmonize_columnsr   r   )
r   r   
exit_stackr   rj   re   r5   rf   has_read_datars   s
             r6   _query_iteratorSQLTable._query_iteratorh  s      ''	2('44   $9<
 '' + (  ::)JJ((T(Bjj +  ZZs   B=BB,#	B=,
B:6B=c           
        SSK Jn  Ub  [        U5      S:  a}  U Vs/ s H  oR                  R                  U   PM     n	nU R
                  bB  U R
                  S S S2    H,  n
U	R                  SU R                  R                  U
   5        M.     U" U	6 nOU" U R                  5      nU R                  R                  U5      nUR                  5       nUb  U R                  UUUUUUUS9$ UR                  5       n[        XX&5      U l        U R                  X6S9  U R
                  b$  U R                  R                  U R
                  SS9  U R                  $ s  snf )Nr   )select)re   r5   rf   r=  Tr  )r   rF  rr   r   cr   r   r   r   r   rC  fetchallr{   r   r@  r   )r   rA  re   r5   rj   r   rf   rF  ncolsidx
sql_selectr   r   rs   s                  r6   readSQLTable.read  sI    	&3w<!#3-45WJJLLOWD5zz%::dd+CKK4::<<#45 ,J

+J$$Z0{{} '')'+ (   ??$D5LDJ ##' $  zz%

$$TZZ$>::C 6s   "Ec                   USL a  U R                   R                  R                  nUb7  [        U[        5      (       d  U/n[        U5      U:w  a  [        SU 35      eU$ US:X  a>  SU R                   R                  ;  a$  U R                   R                  R                  c  S/$ [        R                  " U R                   R                  R                  5      $ [        U[        5      (       a  U/$ [        U[        5      (       a  U$ g )NTz@Length of 'index_label' should match number of levels, which is r+  r   )r   r   nlevelsrI   rl   rr   rM   rj   r   comfill_missing_namesr  r   )r   r   r   rQ  s       r6   r   SQLTable._index_name  s    D=jj&&..G&!+t44#.-K{#w.$,,396  #" 14::#5#55JJ$$))1y --djj.>.>.D.DEE s##7Nt$$Lr8   c           
        / nU R                   bf  [        U R                   5       HM  u  p4U" U R                  R                   R                  U5      5      nUR	                  [        U5      US45        MO     U[        [        U R                  R                  5      5       Vs/ s HI  n[        U R                  R                  U   5      U" U R                  R                  S S 2U4   5      S4PMK     sn-  nU$ s  snf )NTF)
r   rY   r   _get_level_valuesro   r   rq   rr   rj   iloc)r   dtype_mappercolumn_names_and_typesr^   	idx_labelidx_types         r6   _get_column_names_and_types$SQLTable._get_column_names_and_types  s    !#::! )$** 5'

(8(8(J(J1(MN&--s9~x.NO !6 	3tzz1123#
3 ##A&'djjooad6K)LeT3#
 	

 &%#
s   !AC8c                   SSK JnJnJn  SSKJn  U R                  U R                  5      nU VVVs/ s H  u  pgnU" XgUS9PM     n	nnnU R                  bZ  [        U R                  5      (       d  U R                  /n
OU R                  n
U" U
SU R                  S-   06nU	R                  U5        U R                  =(       d     U R                  R                  R                  nU" 5       nU" U R                  U/U	Q7SU06$ s  snnnf )Nr   )ColumnPrimaryKeyConstraintr)   MetaData)r   r   _pkr   )r   r_  r`  r)   r   rb  r\  _sqlalchemy_typer   r   r   ro   r   r   r   )r   r_  r`  r)   rb  rY  r   typis_indexrj   r   pkcr   r   s                 r6   r   SQLTable._create_table_setup  s    	
 	

 	/!%!A!A$BWBW!X (>
'=#8 4H-'= 	 

 99 		**		{yy&E499u3DECNN37 0 0 7 7 zTYY>w>v>>%
s   Dc                   [        U5      nU R                  R                   GH1  nUR                  n U R                  U   nXA;   a   X   n[        XVS9U R                  U'   MB  U R                  UR                  5      nU[        L d  U[        L d	  U[        L a   U[        L n[        XXS9U R                  U'   M  US:X  a(  U[        L a  UR                  USS9U R                  U'   M  US:X  ae  [        U5      UR                  5       :X  aE  U[         R"                  " S5      L d	  U[$        L a   UR                  USS9U R                  U'   GM+  GM.  GM1  GM4     g! [
         a    Sn GNf = f! [&         a     GMX  f = f)a  
Make the DataFrame's column types align with the SQL table
column types.
Need to work around limited NA value support. Floats are always
fine, ints must always be floats if there are Null values.
Booleans are hard because converting bool column with None replaces
all Nones with false. Therefore only convert bool if there are no
NA values.
Datetimes should already be converted to np.datetime64 if supported,
but here we also force conversion if required.
NrX   rG   rc   F)r  int64)r7   r   rj   r   r   rL   rV   
_get_dtyperP   r	   r   r   floatr~   rr   countrQ   rO   boolr[   )	r   r5   rf   sql_colr_   r`   ra   col_typerF   s	            r6   r@  SQLTable._harmonize_columns  sf     4K@zz))G||H!H- *#)3 ,?v+RDJJx(  ??7<<8 (4'?2 #o5C+>v+ODJJx("g-(e2C+1===+NDJJx("g-#f+2O288G#44D8H/5}}XE}/R

8, 9I 3P-= * % #"#0  sI   E,EE,$AE,:,E,(A"E,E)%E,(E))E,,
E;:E;c                   U R                   =(       d    0 n[        U5      (       a.  [        [        U5      nUR                  U;   a  X!R                     $ [
        R                  " USS9nSSKJnJ	nJ
nJnJnJn	Jn
JnJnJn  US;   a!   UR$                  R&                  b  U" SS9$  U$ US:X  a$  [,        R.                  " S	[0        [3        5       S
9  U$ US:X  a  UR                   S:X  a  U	" SS9$ U	" SS9$ US:X  a  UR                   R                  R5                  5       S;   a  U$ UR                   R                  R5                  5       S;   a  U
$ UR                   R                  R5                  5       S:X  a  [7        S5      eU$ US:X  a  U$ US:X  a  U$ US:X  a  U$ US:X  a  [7        S5      eU$ ! [(         a    [+        USS 5      b  U" SS9s $  U$ f = f)NTskipnar   )
	TIMESTAMP
BigIntegerBooleanDateDateTimeFloatIntegerSmallIntegerTextTime)
datetime64r	   )timezonetztimedelta64lthe 'timedelta' type is not supported, and will be written as integer values (ns frequency) to the database.r   rR   float32   )	precision5   rS   )int8uint8int16)uint16int32uint64z1Unsigned 64 bit integer datatype is not supportedbooleanr   r
   complexComplex datatypes not supported)rO   r   r   rJ   r   r   infer_dtypesqlalchemy.typesru  rv  rw  rx  ry  rz  r{  r|  r}  r~  r  r  AttributeErrorgetattrr   r   r   r   lowerrM   )r   rT   rO   rp  ru  rv  rw  rx  ry  rz  r{  r|  r}  r~  s                 r6   rd  SQLTable._sqlalchemy_type>  s   ***u%Exx5 XX& ??3t4	
 	
 	
 1146699($d33 ) O}$MML+-	 #yyI%r**r**"yy~~##%)CC##%%'+>>%%'83 !TUU!!"NKK">??M " 4 3d+7$d33 8O4s   F. .GGc                   SSK JnJnJnJnJnJn  [        X5      (       a  [        $ [        X5      (       a  [        R                  " S5      $ [        X5      (       a  UR                  (       d  [        $ [        $ [        X5      (       a  [        $ [        X5      (       a  [        $ [        X5      (       a  [        $ [         $ )Nr   )ru  rw  rx  ry  rz  r{  rj  )r  ru  rw  rx  ry  rz  r{  rI   rl  rQ   rO   r  r	   r   r   rn  r  )r   sqltyperu  rw  rx  ry  rz  r{  s           r6   rk  SQLTable._get_dtype  s    	
 	
 g%%L))88G$$++##""**O&&K))Kr8   )
rO   r   r   r   r   r   r   r   r   r   )NTr   pandasNNNN)r   r   r   bool | str | list[str] | Noner   $Literal['fail', 'replace', 'append']r   r   rO   DtypeArg | NonereturnNoner  r   r  r  )r   	list[str]r  int)r  z"tuple[list[str], list[np.ndarray]])NN)r   
int | Noner   "Literal['multi'] | Callable | Noner  r  )TNrc   )rA  r   r   r  re   rn  rf   DtypeBackend | Literal['numpy'])TNNNrc   )
rA  r   re   rn  r   r  rf   r  r  DataFrame | Iterator[DataFrame])Nrc   )rf   r  r  r  )rT   zIndex | Series)__name__
__module____qualname____firstlineno____doc__r   r   r   r   r   r   r  r'  r   rC  rN  r   r\  r   r@  rd  rk  __static_attributes__r   r8   r6   r   r     so    /3:@!%";";
 -"; 8"; "; "; 
";H=E
4# "2'l !%59,, 3, 
	,h "9@"! "! 	"! "! 7"!N " $9@-- - - 7- 
)-^@&?@ 9@5 75 
	5nENr8   r   c                  L   \ rS rSrSrSS jrSS jr       S             SS jjr\       S             SS jj5       r	\        S               SS jj5       r
\SSS	 jj5       r\SSS
 jj5       r\   S           SS jj5       rSrg)r   i  z1
Subclasses Should define read_query and to_sql.
c                    U $ r   r   r   s    r6   	__enter__PandasSQL.__enter__  s    r8   c                    g r   r   r   argss     r6   __exit__PandasSQL.__exit__  s    r8   Nc	                    [         er   r   )	r   r   r   re   r5   rj   r   r   rf   s	            r6   r   PandasSQL.read_table  s
     "!r8   c	                    g r   r   )	r   r   r   re   r5   r   r   rO   rf   s	            r6   r   PandasSQL.read_query  s     	r8   c                    g r   r   )r   r   r   r   r   r   r   r   rO   r   r   r   s               r6   r   PandasSQL.to_sql  s     	r8   c                    g r   r   )r   r   r   s      r6   r   PandasSQL.execute      r8   c                    g r   r   )r   r   r   s      r6   r   PandasSQL.has_table  r  r8   c                    g r   r   r   r   r   r   rO   r   s         r6   _create_sql_schemaPandasSQL._create_sql_schema  s     	r8   r   )r  r0   r  NTNNNNrc   r   r   r   str | list[str] | Nonere   rn  r   
str | Noner   r  rf   r  r  r  r   r   r   r  re   rn  r   r  rO   r  rf   r  r  r  r   TNNNNNauto)r   r   r   r  r   rn  r   r  rO   r  r   r  r   r   r  r  r   r   zstr | Select | TextClauser   r   r   r  r  rn  NNNr   r    r   r   r   list[str] | NonerO   r  r   r  r  r   )r  r  r  r  r  r  r  r   r   r   r   r   r   r  r  r   r8   r6   r   r     s    -1!! $9@"" *" 	" " " 7" 
)"  -1! $!%9@ * 	   7 
)  
 ;A $!%59  8	
    3  
       
 "&!%!  	
   
 r8   c                  <    \ rS rSr    S         SS jjrSrg)
BaseEnginei  Nc	                    [        U 5      e)z*
Inserts data into already-prepared table
)r   )
r   r   r   r   r   r   r   r   r   r   s
             r6   insert_recordsBaseEngine.insert_records  s     "$''r8   r   TNNN
r   r   r   r   r   r  r   r  r  r  )r  r  r  r  r  r  r   r8   r6   r  r    sJ     04 $((
 ( -( ( 
( (r8   r  c                  F    \ rS rSrSS jr    S         SS jjrSrg)	SQLAlchemyEnginei  c                    [        SSS9  g )Nr   z'sqlalchemy is required for SQL support.)extrar   r   s    r6   r   SQLAlchemyEngine.__init__  s    " I	
r8   Nc	                    SSK Jn
   UR                  XxS9$ ! U
R                   aE  nSn[	        UR
                  5      n[        R                  " X5      (       a  [        S5      UeUeS nAff = f)Nr   )exc)r   r   zg(\(1054, "Unknown column 'inf(e0)?' in 'field list'"\))(?#
            )|inf can not be used with MySQLzinf cannot be used with MySQL)	r   r  r   StatementErrorr   origresearchrM   )r   r   r   r   r   r   r   r   r   r   r  r  msgerr_texts                 r6   r  SQLAlchemyEngine.insert_records  si     	#
	<<)<CC!! 	0C388}Hyy'' !@AsJI	s    A,A A''A,r   r  r  r  )r  r  r  r  r   r  r  r   r8   r6   r  r    sO    
 04 $
  -  
 r8   r  c                   U S:X  a  [        S5      n U S:X  a(  [        /nSnU H  n U" 5       s  $    [        SU 35      eU S:X  a
  [        5       $ [	        S5      e! [         a  nUS[        U5      -   -  n SnAMY  SnAff = f)	zreturn our implementationr  zio.sql.engine z
 - NzUnable to find a usable engine; tried using: 'sqlalchemy'.
A suitable version of sqlalchemy is required for sql I/O support.
Trying to import the above resulted in these errors:r   z*engine must be one of 'auto', 'sqlalchemy')r   r  r   r   rM   )r   engine_classes
error_msgsengine_classr  s        r6   
get_enginer  "  s    O,*+
*L1#~% + C l
 	
 !!
A
BB!  1gC00
1s   A
B%A<<Bc                     \ rS rSrSr S     SS jjrSS jr\S 5       rSSS jjr	       S             SS jjr
\     S         SS	 jj5       r       S             SS
 jjr\r     S         SS jjr      S S jr        S!                 S"S jjr\S 5       rSS#S jjrSS$S jjrSS%S jjr   S&           S'S jjrSrg)(r   iB  a-  
This class enables conversion between DataFrame and SQL databases
using SQLAlchemy to handle DataBase abstraction.

Parameters
----------
con : SQLAlchemy Connectable or URI string.
    Connectable to connect with the database. Using SQLAlchemy makes it
    possible to use any DB supported by that library.
schema : string, default None
    Name of SQL schema in database to write to (if database flavor
    supports this). If None, use default schema (default).
need_transaction : bool, default False
    If True, SQLDatabase will create a transaction.

Nc                   SSK Jn  SSKJn  SSKJn  [        5       U l        [        U[        5      (       a-  U" U5      nU R                  R                  UR                  5        [        X5      (       a)  U R                  R                  UR                  5       5      nU(       a>  UR                  5       (       d)  U R                  R                  UR                  5       5        Xl        U" US9U l        SU l        g )Nr   )create_engine)r   ra  r   F)r   r  sqlalchemy.enginer   r   rb  r   rA  rI   r   callbackdisposeenter_contextconnectin_transactionbeginr   r   returns_generator)r   r   r   r   r  r   rb  s          r6   r   SQLDatabase.__init__T  s     	-,. $+c3$COO$$S[[1c""////>CC$6$6$8$8OO))#))+6F+	!&r8   c                \    U R                   (       d  U R                  R                  5         g g r   )r  rA  closer  s     r6   r  SQLDatabase.__exit__k  s     %%OO!!# &r8   c              #     #    U R                   R                  5       (       d2  U R                   R                  5          U R                   v   S S S 5        g U R                   v   g ! , (       d  f       g = f7fr   )r   r  r  r   s    r6   r   SQLDatabase.run_transactiono  sJ     xx&&((!hh "! ((N "!s   :A4A#A4#
A1-A4c                    Uc  / OU/n[        U[        5      (       a  U R                  R                  " U/UQ76 $ U R                  R                  " U/UQ76 $ )z,Simple passthrough to SQLAlchemy connectable)rI   r   r   exec_driver_sqlr   )r   r   r   r  s       r6   r   SQLDatabase.executew  sP    ^r&c388++C7$77xx+d++r8   c	           	         U R                   R                  U R                  U/SS9  [        XX&S9n	Ub  SU l        U	R                  U R                  UUUUUS9$ )a  
Read SQL database table into a DataFrame.

Parameters
----------
table_name : str
    Name of SQL table in database.
index_col : string, optional, default: None
    Column to set as index.
coerce_float : bool, default True
    Attempts to convert values of non-string, non-numeric objects
    (like decimal.Decimal) to floating point. This can result in
    loss of precision.
parse_dates : list or dict, default: None
    - List of column names to parse as dates.
    - Dict of ``{column_name: format string}`` where format string is
      strftime compatible in case of parsing string times, or is one of
      (D, s, ns, ms, us) in case of parsing integer timestamps.
    - Dict of ``{column_name: arg}``, where the arg corresponds
      to the keyword arguments of :func:`pandas.to_datetime`.
      Especially useful with databases without native Datetime support,
      such as SQLite.
columns : list, default: None
    List of column names to select from SQL table.
schema : string, default None
    Name of SQL schema in database to query (if database flavor
    supports this).  If specified, this overwrites the default
    schema of the SQL database object.
chunksize : int, default None
    If specified, return an iterator where `chunksize` is the number
    of rows to include in each chunk.
dtype_backend : {'numpy_nullable', 'pyarrow'}, default 'numpy_nullable'
    Back-end data type applied to the resultant :class:`DataFrame`
    (still experimental). Behaviour is as follows:

    * ``"numpy_nullable"``: returns nullable-dtype-backed :class:`DataFrame`
      (default).
    * ``"pyarrow"``: returns pyarrow-backed nullable :class:`ArrowDtype`
      DataFrame.

    .. versionadded:: 2.0

Returns
-------
DataFrame

See Also
--------
pandas.read_sql_table
SQLDatabase.read_query

T)r   onlyviews)r   r   )re   r5   rj   r   rf   )r   reflectr   r   r  rN  rA  )
r   r   r   re   r5   rj   r   r   rf   r   s
             r6   r   SQLDatabase.read_table~  sj    ~ 			txxzl$GJ %)D"zzOO%#'  
 	
r8   c	              #     #    Sn	U    U R                  U5      n
U
(       d  U	(       d  [        / UUUUUUS9v   OSn	[        U
UUUUUUS9v   MF  SSS5        g! , (       d  f       g= f7f)+Return generator through chunked result setFTr   re   r5   rO   rf   N)r>  r   )r   rA  r   rj   r   re   r5   rO   rf   rB  rs   s              r6   rC  SQLDatabase._query_iterator  s      ''	2(*#&/)5(3"'*7   $"'!- +"/ !  ZZs   A)AA	A)
A&"A)c	                    U R                  X5      n	U	R                  5       n
Ub(  SU l        U R                  U	U R                  UU
UUUUUS9	$ U	R                  5       n[        UU
UUUUUS9nU$ )a  
Read SQL query into a DataFrame.

Parameters
----------
sql : str
    SQL query to be executed.
index_col : string, optional, default: None
    Column name to use as index for the returned DataFrame object.
coerce_float : bool, default True
    Attempt to convert values of non-string, non-numeric objects (like
    decimal.Decimal) to floating point, useful for SQL result sets.
params : list, tuple or dict, optional, default: None
    List of parameters to pass to execute method.  The syntax used
    to pass parameters is database driver dependent. Check your
    database driver documentation for which of the five syntax styles,
    described in PEP 249's paramstyle, is supported.
    Eg. for psycopg2, uses %(name)s so use params={'name' : 'value'}
parse_dates : list or dict, default: None
    - List of column names to parse as dates.
    - Dict of ``{column_name: format string}`` where format string is
      strftime compatible in case of parsing string times, or is one of
      (D, s, ns, ms, us) in case of parsing integer timestamps.
    - Dict of ``{column_name: arg dict}``, where the arg dict
      corresponds to the keyword arguments of
      :func:`pandas.to_datetime` Especially useful with databases
      without native Datetime support, such as SQLite.
chunksize : int, default None
    If specified, return an iterator where `chunksize` is the number
    of rows to include in each chunk.
dtype : Type name or dict of columns
    Data type for data or columns. E.g. np.float64 or
    {'a': np.float64, 'b': np.int32, 'c': 'Int64'}

    .. versionadded:: 1.3.0

Returns
-------
DataFrame

See Also
--------
read_sql_table : Read SQL database table into a DataFrame.
read_sql

Tr	  )r   r   r  rC  rA  rI  r   )r   r   r   re   r5   r   r   rO   rf   r   rj   rs   r   s                r6   r   SQLDatabase.read_query  s    r c*++- %)D"''#)'+ ( 
 
 ??$D #)'+E Lr8   c                   U(       a  [        U5      (       d  U Vs0 s H  oU_M     nnO[        [        U5      nSSKJn	  UR                  5        HK  u  p[        U[        5      (       a  [        X5      (       a  M,  [        X5      (       a  M>  [        SU
 S35      e   [        UU UUUUUUS9nUR                  5         U$ s  snf )zO
Prepares table in the database for data insertion. Creates it if needed, etc.
r   )
TypeEnginezThe type of z is not a SQLAlchemy type)r   r   r   r   r   rO   )r   r   rJ   r  r  rZ   rI   rP   rN   rM   r   r   )r   r   r   r   r   r   r   rO   r_   r  rT   my_typer   s                r6   
prep_tableSQLDatabase.prep_tableK  s     && :??X5?T5)3 %gt,,G1P1P44$|C58Q%RSS !. #	
 	3 @s   Cc                @   UR                  5       (       d  UR                  5       (       ds  SSKJn  U" U R                  5      nUR                  U=(       d    U R                  R                  S9nX;  a)  SU S3n[        R                  " U[        [        5       S9  gggg)z^
Checks table name for issues with case-sensitivity.
Method is called after data is inserted.
r   inspectr   zThe provided table name 'z' is not found exactly as such in the database after writing the table, possibly due to case sensitivity issues. Consider using lower case table names.r   N)isdigitislowerr   r  r   get_table_namesr   r   r   r   r   r   )r   r   r   sqlalchemy_inspectinsptable_namesr  s          r6   check_case_sensitive SQLDatabase.check_case_sensitive{  s     ||~~dllnn A%dhh/D..f6P		@P@P.QK&/v 6( (  /1 ' '5~r8   c                    [        U
5      nU R                  UUUUUUUS9nUR                  " SUU R                  UUUUUU	S.UD6nU R	                  X&S9  U$ )a  
Write records stored in a DataFrame to a SQL database.

Parameters
----------
frame : DataFrame
name : string
    Name of SQL table.
if_exists : {'fail', 'replace', 'append'}, default 'fail'
    - fail: If table exists, do nothing.
    - replace: If table exists, drop it, recreate it, and insert data.
    - append: If table exists, insert data. Create if does not exist.
index : boolean, default True
    Write DataFrame index as a column.
index_label : string or sequence, default None
    Column label for index column(s). If None is given (default) and
    `index` is True, then the index names are used.
    A sequence should be given if the DataFrame uses MultiIndex.
schema : string, default None
    Name of SQL schema in database to write to (if database flavor
    supports this). If specified, this overwrites the default
    schema of the SQLDatabase object.
chunksize : int, default None
    If not None, then rows will be written in batches of this size at a
    time.  If None, all rows will be written at once.
dtype : single type or dict of column name to SQL type, default None
    Optional specifying the datatype for columns. The SQL type should
    be a SQLAlchemy type. If all columns are of the same type, one
    single value can be used.
method : {None', 'multi', callable}, default None
    Controls the SQL insertion clause used:

    * None : Uses standard SQL ``INSERT`` clause (one per row).
    * 'multi': Pass multiple values in a single ``INSERT`` clause.
    * callable with signature ``(pd_table, conn, keys, data_iter)``.

    Details and a sample callable implementation can be found in the
    section :ref:`insert method <io.sql.method>`.
engine : {'auto', 'sqlalchemy'}, default 'auto'
    SQL engine library to use. If 'auto', then the option
    ``io.sql.engine`` is used. The default ``io.sql.engine``
    behavior is 'sqlalchemy'

    .. versionadded:: 1.3.0

**engine_kwargs
    Any additional kwargs are passed to the engine.
)r   r   r   r   r   r   rO   )r   r   r   r   r   r   r   r   )r   r   r   )r  r  r  r   r  )r   r   r   r   r   r   r   r   rO   r   r   r   
sql_enginer   r7  s                  r6   r   SQLDatabase.to_sql  s    |  '
#   
 $22 



 

 	!!t!;r8   c                .    U R                   R                  $ r   )r   tablesr   s    r6   r!  SQLDatabase.tables  s    yyr8   c                    SSK Jn  U" U R                  5      nUR                  X=(       d    U R                  R
                  5      $ )Nr   r  )r   r  r   r   r   r   )r   r   r   r  r  s        r6   r   SQLDatabase.has_table  s1    <!$((+~~d$>dii.>.>??r8   c                   SSK JnJn  U=(       d    U R                  R                  nU" XR                  U R
                  US9nUR                   H1  n[        UR                  U5      (       d  M   SUR                  l	        M3     U$ )Nr   )Numericr)   )autoload_withr   F)
r   r&  r)   r   r   r   rj   rI   rP   	asdecimal)r   r   r   r&  r)   tblcolumns          r6   r   SQLDatabase.get_table  se    	

 +499++J		&QkkF&++w//(-% " 
r8   c                   U=(       d    U R                   R                  nU R                  X5      (       a  U R                   R                  U R                  U/USS9  U R                  5          U R                  X5      R                  U R                  S9  S S S 5        U R                   R                  5         g g ! , (       d  f       N*= f)NT)r   r  r   r  r   )	r   r   r   r  r   r   r   dropclearr   r   r   s      r6   r   SQLDatabase.drop_table  s    +499++>>*--IIXXZLt   %%'z277TXX7F (IIOO . ('s   -)B::
Cc           
     R    [        UU USUUUS9n[        UR                  5       5      $ NF)r   r   r   rO   r   )r   r   r   r   r   r   r   rO   r   r   s          r6   r  SQLDatabase._create_sql_schema  s9     
 5##%&&r8   )r   rA  r   r  NF)r   r  r   rn  r  r  r  r   r  r  r  NTNNrc   )
rA  r   r   r  re   rn  rO   r  rf   r  r  )r   TNNN)
r   r   r   r  r   r  rO   r  r  r   r   r   r   r  r  r  r  r   r   r   r  r   rn  r   r  r   r  rO   r  r   r  r   r   r  r  r  )r   r   r   r  r  r)   r   r   r   r  r  r  r  r  )r  r  r  r  r  r   r  r   r   r   r   staticmethodrC  r   r   r  r  r   propertyr!  r   r   r   r  r  r   r8   r6   r   r   B  s   $ HM'%'@D'	'.$  , -1!! $9@J
J
 *J
 	J
 J
 J
 7J
 
)J
X  !!%9@&& & & & 7& &V -1! $!%9@TT *T 	T T T 7T 
)Tl H ;A/3!%. . 8	.
 -. . 
.`  
	B ;A! $!%59W W 8	W
 W W W W 3W W 
Wr    @ "&!%!'' ' 	'
 ' ' 
' 'r8   r   c                  (   \ rS rSrSrSS jr\S 5       rSSS jjr       S             SS jjr	       S             SS jjr
\
r        S                 SS	 jjrSSS
 jjr   S           SS jjrSrg)r   i)  z
This class enables conversion between DataFrame and SQL databases
using ADBC to handle DataBase abstraction.

Parameters
----------
con : adbc_driver_manager.dbapi.Connection
c                    Xl         g r   r   r   r   s     r6   r   ADBCDatabase.__init__3      r8   c              #    #    U R                   R                  5        n Uv   U R                   R	                  5         S S S 5        g ! [         a    U R                   R                  5         e f = f! , (       d  f       g = f7fr   )r   cursorr   rollbackcommitr   curs     r6   r   ADBCDatabase.run_transaction6  sc     XX__#	 HHOO   !!# s1   B A/AA/	B &A,,A//
A=9B Nc           	        [        U[        5      (       d  [        S5      eUc  / OU/nU R                  R	                  5       n UR
                  " U/UQ76   U$ ! [         aZ  n U R                  R                  5         O&! [         a  n[        SU SU S35      nXveS nAff = f[        SU SU 35      nXueS nAff = fNz/Query must be a string unless using sqlalchemy.zExecution failed on sql: 
z
unable to rollbackzExecution failed on sql 'z': 	rI   r   rL   r   rC  r   r   rD  r   r   r   r   r  rG  r  	inner_excexs           r6   r   ADBCDatabase.execute@      #s##MNN^r&hhoo	KK#d#J 
	(!!# ("/uBse;OP '	( !:3%s3%HIB
	6   A 
B=$A?>B8?
B"	BB""B88B=c	                `   USLa  [        S5      eU(       a  [        S5      eU(       a2  U(       a  [        U5      n	O/ n	X-   n
SR                  S U
 5       5      nOSnU(       a  SU SU S	U 3nOSU SU 3nUS
:X  a  [        nO=US:X  a  SSKJn  U" 5       R                  nO[        5       (       a  SSKJn  U" 5         OSnU R                  R                  5        nUR                  U5        UR                  5       R                  WS9nSSS5        [        WUUS9$ ! , (       d  f       N= f)a  
Read SQL database table into a DataFrame.

Parameters
----------
table_name : str
    Name of SQL table in database.
coerce_float : bool, default True
    Raises NotImplementedError
parse_dates : list or dict, default: None
    - List of column names to parse as dates.
    - Dict of ``{column_name: format string}`` where format string is
      strftime compatible in case of parsing string times, or is one of
      (D, s, ns, ms, us) in case of parsing integer timestamps.
    - Dict of ``{column_name: arg}``, where the arg corresponds
      to the keyword arguments of :func:`pandas.to_datetime`.
      Especially useful with databases without native Datetime support,
      such as SQLite.
columns : list, default: None
    List of column names to select from SQL table.
schema : string, default None
    Name of SQL schema in database to query (if database flavor
    supports this).  If specified, this overwrites the default
    schema of the SQL database object.
chunksize : int, default None
    Raises NotImplementedError
dtype_backend : {'numpy_nullable', 'pyarrow'}, default 'numpy_nullable'
    Back-end data type applied to the resultant :class:`DataFrame`
    (still experimental). Behaviour is as follows:

    * ``"numpy_nullable"``: returns nullable-dtype-backed :class:`DataFrame`
      (default).
    * ``"pyarrow"``: returns pyarrow-backed nullable :class:`ArrowDtype`
      DataFrame.

    .. versionadded:: 2.0

Returns
-------
DataFrame

See Also
--------
pandas.read_sql_table
SQLDatabase.read_query

T2'coerce_float' is not implemented for ADBC drivers/'chunksize' is not implemented for ADBC drivers, c              3  .   #    U  H  nS U S 3v   M     g7f)"Nr   )r-  xs     r6   r0  *ADBCDatabase.read_table.<locals>.<genexpr>  s     #@ias!His   *zSELECT z FROM .rg   numpy_nullabler   _arrow_dtype_mapping)arrow_string_types_mapperNtypes_mapper)r   r5   )r   r$   joinr   pandas.io._utilr_  getr   r`  r   rC  r   fetch_arrow_table	to_pandasr   )r   r   r   re   r5   rj   r   r   rf   index_select	to_selectselect_listr  mappingr_  r`  rG  rz   s                     r6   r   ADBCDatabase.read_tableT  s/   t t#%D  %&WXX.y9!$.I))#@i#@@KK[MxqED[M
|<D I% G..<*,00G'))A%'GXX__#KK&&(222HB  !#
 	
	 s   /D
D-c	                   USLa  [        S5      eU(       a  [        S5      eU(       a  [        S5      eUS:X  a  [        n	O US:X  a  SSKJn
  U
" 5       R                  n	OS	n	U R
                  R                  5        nUR                  U5        UR                  5       R                  U	S
9nS	S	S	5        [        WUUUS9$ ! , (       d  f       N= f)a  
Read SQL query into a DataFrame.

Parameters
----------
sql : str
    SQL query to be executed.
index_col : string, optional, default: None
    Column name to use as index for the returned DataFrame object.
coerce_float : bool, default True
    Raises NotImplementedError
params : list, tuple or dict, optional, default: None
    Raises NotImplementedError
parse_dates : list or dict, default: None
    - List of column names to parse as dates.
    - Dict of ``{column_name: format string}`` where format string is
      strftime compatible in case of parsing string times, or is one of
      (D, s, ns, ms, us) in case of parsing integer timestamps.
    - Dict of ``{column_name: arg dict}``, where the arg dict
      corresponds to the keyword arguments of
      :func:`pandas.to_datetime` Especially useful with databases
      without native Datetime support, such as SQLite.
chunksize : int, default None
    Raises NotImplementedError
dtype : Type name or dict of columns
    Data type for data or columns. E.g. np.float64 or
    {'a': np.float64, 'b': np.int32, 'c': 'Int64'}

    .. versionadded:: 1.3.0

Returns
-------
DataFrame

See Also
--------
read_sql_table : Read SQL database table into a DataFrame.
read_sql

TrT  z,'params' is not implemented for ADBC driversrU  rg   r]  r   r^  Nra  )r   r5   rO   )r   r   rd  r_  re  r   rC  r   rf  rg  r   )r   r   r   re   r5   r   r   rO   rf   rk  r_  rG  rz   s                r6   r   ADBCDatabase.read_query  s    f t#%D  %&TUU%&WXX I% G..<*,00GGXX__#KK&&(222HB  !#	
 	
	 s   </B??
Cc                $   U(       a  [        S5      eU(       a  [        S5      eU(       a  [        S5      eU	(       a  [        S5      eU
S:w  a  [        S5      eU(       a  U SU 3nOUnSnU R                  X&5      (       a[  US	:X  a  [        S
U S35      eUS:X  a8  U R                  R	                  5        nUR                  SU 35        SSS5        OUS:X  a  SnSSKn UR                  R                  XS9nU R                  R	                  5        nUR                  UUXS9nSSS5        U R                  R                  5         W$ ! , (       d  f       N|= f! UR                   a  n[        S5      UeSnAff = f! , (       d  f       N_= f)a$  
Write records stored in a DataFrame to a SQL database.

Parameters
----------
frame : DataFrame
name : string
    Name of SQL table.
if_exists : {'fail', 'replace', 'append'}, default 'fail'
    - fail: If table exists, do nothing.
    - replace: If table exists, drop it, recreate it, and insert data.
    - append: If table exists, insert data. Create if does not exist.
index : boolean, default True
    Write DataFrame index as a column.
index_label : string or sequence, default None
    Raises NotImplementedError
schema : string, default None
    Name of SQL schema in database to write to (if database flavor
    supports this). If specified, this overwrites the default
    schema of the SQLDatabase object.
chunksize : int, default None
    Raises NotImplementedError
dtype : single type or dict of column name to SQL type, default None
    Raises NotImplementedError
method : {None', 'multi', callable}, default None
    Raises NotImplementedError
engine : {'auto', 'sqlalchemy'}, default 'auto'
    Raises NotImplementedError if not set to 'auto'
z1'index_label' is not implemented for ADBC driversrU  z+'dtype' is not implemented for ADBC driversz,'method' is not implemented for ADBC driversr  z1engine != 'auto' not implemented for ADBC driversr\  r   r   r   r   r   DROP TABLE Nro   r   )preserve_indexzdatatypes not supported)r   rs   modedb_schema_name)r   r   rM   r   rC  r   rg   r)   rh   ArrowNotImplementedErroradbc_ingestrE  )r   r   r   r   r   r   r   r   rO   r   r   r   r   rr  rG  rv   r)  r  r7  s                      r6   r   ADBCDatabase.to_sql	  s   V %C  %&WXX%&STT%&TUUV%C  "81TF+JJ >>$''F" 7:,6G!HIIi'XX__&#KK+j\ :; '&h&	A((&&u&CC XX__# __c - N 
 	% '& ** 	A67S@	A s0   8E#E F
EE>-E99E>
Fc                    U R                   R                  X!S9R                  5       nUS   R                  5        H7  nU(       d  M  U H%  nU(       d  M  US    H  nUS   U:X  d  M        g   M'     M9     g)N)db_schema_filtertable_name_filtercatalog_db_schemasdb_schema_tablesr   TF)r   adbc_get_objectsread_all	to_pylist)r   r   r   r   catalog_schemaschema_recordtable_records          r6   r   ADBCDatabase.has_tablej	  s    xx((# ) 

(* 	 ##78BBDN!!/$$12D$EL#L1T9# %F	 "0 E r8   c                    [        S5      e)Nznot implemented for adbcr  r  s         r6   r  ADBCDatabase._create_sql_schema|	  s     ""<==r8   r>  r  r   r  r  r  r  r  r8  r  r  r  )r  r  r  r  r  r   r   r   r   r   r   r   r   r   r  r  r   r8   r6   r   r   )  s     . -1!! $9@e
e
 *e
 	e
 e
 e
 7e
 
)e
T -1! $!%9@O
O
 *O
 	O
 O
 O
 7O
 
)O
b H ;A! $!%59Z Z 8	Z
 Z Z Z Z 3Z Z 
Zx, "&!%!>> > 	>
 > > 
> >r8   r   TEXTREALINTEGERru  DATETIME)ri   rR   rS   r	   r   r
   r  c                     [        U 5      R                  SS5      R                  S5      nU$ ! [         a  n[	        SU  S35      UeS nAff = f)Nzutf-8strictz%Cannot convert identifier to UTF-8: 'r   )r   encodedecodeUnicodeErrorrM   )r   unamer  s      r6   _get_unicode_namer  	  s[    SD	  (3::7C L  S@aHIsRSs   *. 
AAAc                    [        U 5      n[        U5      (       d  [        S5      eUR                  S5      nUS:  a  [        S5      eSUR	                  SS5      -   S-   $ )Nz$Empty table or column name specified r   z%SQLite identifier cannot contain NULsrX  z"")r  rr   rM   findr   )r   r  	nul_indexs      r6   _get_valid_sqlite_namer  	  s_     d#Eu::?@@

6"IA~@AAsD))C//r8   c                  x   ^  \ rS rSrSrSU 4S jjrSS jrSS jrSS jrSS jr	SS jr
SS	 jrS
 rS rSrU =r$ )SQLiteTablei	  zk
Patch the SQLTable for fallback support.
Instead of a table variable just use the Create Table statement.
c                F   > [         TU ]  " U0 UD6  U R                  5         g r   )superr   _register_date_adapters)r   r  kwargs	__class__s      r6   r   SQLiteTable.__init__	  s!    $)&)$$&r8   c                    SS K nS	S jnS nS nUR                  [        U5        UR                  [        U5        UR                  [        U5        S nS nUR                  SU5        UR                  SU5        g )
Nr   c                t    U R                   S SU R                  S SU R                  S SU R                  S 3$ )N02d:r\  06d)hourminutesecondmicrosecond)ts    r6   _adapt_time8SQLiteTable._register_date_adapters.<locals>._adapt_time	  s8    ffS\188C.!((3qs@STTr8   c                "    U R                  5       $ r   	isoformatvals    r6   <lambda>5SQLiteTable._register_date_adapters.<locals>.<lambda>	  s
    S]]_r8   c                $    U R                  S5      $ )N r  r  s    r6   r  r  	  s    s);r8   c                J    [         R                  " U R                  5       5      $ r   )r   fromisoformatr  r  s    r6   r  r  	  s    4#5#5cjjl#Cr8   c                J    [         R                  " U R                  5       5      $ r   )r	   r  r  r  s    r6   r  r  	  s    (>(>szz|(Lr8   r   	timestampr  )r   register_adapterr
   r   r	   register_converter)r   r   r  adapt_date_isoadapt_datetime_isoconvert_dateconvert_timestamps          r6   r  #SQLiteTable._register_date_adapters	  sw     		U 5;  {3  ~6  +=>CL""6<8"";0ABr8   c                J    [        SR                  U R                  5      5      $ )Nz;
)r   rc  r   r   s    r6   r   SQLiteTable.sql_schema	  s    5::djj)**r8   c                    U R                   R                  5        nU R                   H  nUR                  U5        M     S S S 5        g ! , (       d  f       g = fr   )r   r   r   r   )r   r   r  s      r6   r   SQLiteTable._execute_create	  s:    [[((*d

T" # +**s   %A		
Ac                  [        [        [        U R                  R                  5      5      nSn[
        nU R                  b+  U R                  S S S2    H  nUR                  SU5        M     U Vs/ s H
  od" U5      PM     nnSR                  U5      nSR                  U/[        U5      -  5      n	SR                  [        U5       V
s/ s H	  n
SU	 S3PM     sn
5      nSU" U R                  5       SU S	U 3nU$ s  snf s  sn
f )
N?rG  r   ,()zINSERT INTO  (z	) VALUES )rl   r  r   r   rj   r  r   r   rc  rr   rq   r   )r   num_rowsr  wldescaperL  r*  bracketed_names	col_namesrow_wildcardsr#  	wildcardsinsert_statements                r6   r  SQLiteTable.insert_statement	  s    Sdjj0012'::!zz$B$'Q$ ( 9>>f6&>>HH_-	#U!34HHE(OLOq-2OLM	6$)),-R	{)I;O 	   ? Ms   2D Dc                n    [        U5      nUR                  U R                  SS9U5        UR                  $ )Nr+  r  )rl   executemanyr  r   )r   r   r   r   r"  s        r6   r   SQLiteTable._execute_insert	  s3    O	...:IF}}r8   c                    [        U5      nU VVs/ s H  oU  H  ofPM     M     nnnUR                  U R                  [        U5      S9U5        UR                  $ s  snnf )Nr  )rl   r   r  rr   r   )r   r   r   r   r"  r   rY  flattened_datas           r6   r  !SQLiteTable._execute_insert_multi	  sV    O	'0>y#Q!#!y>T**C	N*C^T}} ?s   Ac                   U R                  U R                  5      n[        nU VVVs/ s H  u  p4oR" U5      S-   U-   PM     nnnnU R                  b  [	        U R                  5      (       a}  [        U R                  5      (       d  U R                  /nOU R                  nSR                  U Vs/ s H
  o" U5      PM     sn5      n	UR                  SU R                   SU	 S35        U R                  (       a  U R                  S-   n
OSn
SU
-   U" U R                  5      -   S	-   S
R                  U5      -   S-   /nU VVVs/ s H  u  p5o(       d  M  UPM     nnnn[	        U5      (       a  SR                  U5      nSR                  U Vs/ s H
  o" U5      PM     sn5      n	UR                  SU" SU R                  -   S-   U-   5      -   S-   U" U R                  5      -   S-   U	-   S-   5        U$ s  snnnf s  snf s  snnnf s  snf )z
Return a list of SQL statements that creates a table reflecting the
structure of a DataFrame.  The first entry will be a CREATE TABLE
statement while the rest will be CREATE INDEX statements.
r  rV  zCONSTRAINT z_pk PRIMARY KEY (r  r\  r  zCREATE TABLE z (
z,
  z
)r#  r  zCREATE INDEX ix_zON r  )
r\  _sql_type_namer  r   rr   r   rc  ro   r   r   )r   rY  r  cnamectyper#  create_tbl_stmtsr   rH  	cnames_brschema_namecreate_stmtsrf  ix_colscnamess                  r6   r   SQLiteTable._create_table_setup	  s    "&!A!A$BUBU!V' @V
?UOE!F5MC%'?U 	 
 99 S^^		**		{yy		d";d6!9d";<I##dii[(9)AF ;;+++KKTYY   ll+,	-
 
 4JV3I/UxX53IVw<<XXg&FW!=W&)W!=>I*S069:; #$ 	
   Q
 #<" W ">s   G50G<HHHc                   U R                   =(       d    0 n[        U5      (       a.  [        [        U5      nUR                  U;   a  X!R                     $ [
        R                  " USS9nUS:X  a%  [        R                  " S[        [        5       S9  SnO#US:X  a  SnOUS	:X  a  S
nOUS:X  a  [        S5      eU[        ;  a  S
n[        U   $ )NTrs  r  r  r   rS   r  r	   emptyri   r  r  )rO   r   r   rJ   r   r   r  r   r   r   r   rM   
_SQL_TYPES)r   rT   rO   rp  s       r6   r  SQLiteTable._sql_type_name/
  s    ***u%Exx5 XX& ??3t4}$MML+-	 !H%!H H">??:%H(##r8   r   r  r  )r  r  r  r   )r  r  )r  r  r  r  r  r   r  r   r   r  r   r  r   r  r  __classcell__)r  s   @r6   r  r  	  s<    
'
C:+#
 &
1f $  $r8   r  c                  ,   \ rS rSrSrSS jr\S 5       rSSS jjr\	     S       SS jj5       r
       S         SS jjrS	 r        S               SS
 jjrSSS jjrSSS jjrSSS jjr   S       SS jjrSrg)r   iR
  z
Version of SQLDatabase to support SQLite connections (fallback without
SQLAlchemy). This should only be used internally.

Parameters
----------
con : sqlite connection object

c                    Xl         g r   r>  r?  s     r6   r   SQLiteDatabase.__init__]
  rA  r8   c              #    #    U R                   R                  5       n Uv   U R                   R                  5          UR                  5         g ! [         a    U R                   R	                  5         e f = f! UR                  5         f = f7fr   )r   rC  rE  r   rD  r  rF  s     r6   r   SQLiteDatabase.run_transaction`
  sg     hhoo	IHHOO
 IIK	  	HH	 IIKs'   BA B&A44A7 7B		BNc           	        [        U[        5      (       d  [        S5      eUc  / OU/nU R                  R	                  5       n UR
                  " U/UQ76   U$ ! [         aZ  n U R                  R                  5         O&! [         a  n[        SU SU S35      nXveS nAff = f[        SU SU 35      nXueS nAff = frJ  rL  rM  s           r6   r   SQLiteDatabase.executel
  rQ  rR  c           
   #  8  #    Sn U R                  U5      n	[        U	5      [        :X  a  [        U	5      n	U	(       dI  U R	                  5         U(       d1  [
        R                  " / X$S9n
U(       a  U
R                  U5      n
U
v   gSn[        U	UUUUUUS9v   M  7f)r  FTr<  r	  N)	r>  rP   tuplerl   r  r    r?  r~   r   )rC  r   rj   r   re   r5   rO   rf   rB  rs   r   s              r6   rC  SQLiteDatabase._query_iterator
  s      ##I.DDzU"Dz$&33GF !'u!5 L M#)'+ ! s   BBc	                    U R                  X5      n	U	R                   V
s/ s H  oS   PM	     nn
Ub  U R                  U	UUUUUUUS9$ U R                  U	5      nU	R	                  5         [        UUUUUUUS9nU$ s  sn
f )Nr   r	  )r   descriptionrC  _fetchall_as_listr  r   )r   r   r   re   r5   r   r   rO   rf   rC  col_descrj   rs   r   s                 r6   r   SQLiteDatabase.read_query
  s     c*/5/A/AB/A8A;/AB ''#)'+ ( 	 	 ))&1DLLN #)'+E L5 Cs   A;c                f    UR                  5       n[        U[        5      (       d  [        U5      nU$ r   )rI  rI   rl   )r   rG  r   s      r6   r   SQLiteDatabase._fetchall_as_list
  s(    &$''&\Fr8   c           
     ^   U(       ar  [        U5      (       d  U Vs0 s H  oU_M     nnO[        [        U5      nUR                  5        H+  u  p[	        U[
        5      (       a  M  [        U SU S35      e   [        UU UUUUUS9nUR                  5         UR                  Xy5      $ s  snf )a0  
Write records stored in a DataFrame to a SQL database.

Parameters
----------
frame: DataFrame
name: string
    Name of SQL table.
if_exists: {'fail', 'replace', 'append'}, default 'fail'
    fail: If table exists, do nothing.
    replace: If table exists, drop it, recreate it, and insert data.
    append: If table exists, insert data. Create if it does not exist.
index : bool, default True
    Write DataFrame index as a column
index_label : string or sequence, default None
    Column label for index column(s). If None is given (default) and
    `index` is True, then the index names are used.
    A sequence should be given if the DataFrame uses MultiIndex.
schema : string, default None
    Ignored parameter included for compatibility with SQLAlchemy
    version of ``to_sql``.
chunksize : int, default None
    If not None, then rows will be written in batches of this
    size at a time. If None, all rows will be written at once.
dtype : single type or dict of column name to SQL type, default None
    Optional specifying the datatype for columns. The SQL type should
    be a string. If all columns are of the same type, one single value
    can be used.
method : {None, 'multi', callable}, default None
    Controls the SQL insertion clause used:

    * None : Uses standard SQL ``INSERT`` clause (one per row).
    * 'multi': Pass multiple values in a single ``INSERT`` clause.
    * callable with signature ``(pd_table, conn, keys, data_iter)``.

    Details and a sample callable implementation can be found in the
    section :ref:`insert method <io.sql.method>`.
r  z) not a string)r   r   r   r   rO   )
r   r   rJ   rZ   rI   r   rM   r  r   r   )r   r   r   r   r   r   r   r   rO   r   r   r   r_   rT   r  r   s                   r6   r   SQLiteDatabase.to_sql
  s    h && :??X5?T5) %!'3//$uBwi~%FGG !. #
 	||I..% @s   B*c                j    SnSU S3n[        U R                  XA/5      R                  5       5      S:  $ )Nr  z
        SELECT
            name
        FROM
            sqlite_master
        WHERE
            type IN ('table', 'view')
            AND name=z
;
        r   )rr   r   rI  )r   r   r   r  querys        r6   r   SQLiteDatabase.has_table%  sE     U 	 4<<v.779:Q>>r8   c                    g r   r   r/  s      r6   r   SQLiteDatabase.get_table3  s    r8   c                B    S[        U5       3nU R                  U5        g )Nrp  )r  r   )r   r   r   drop_sqls       r6   r   SQLiteDatabase.drop_table6  s!     !7!= >?Xr8   c           
     R    [        UU USUUUS9n[        UR                  5       5      $ r2  )r  r   r   r3  s          r6   r  !SQLiteDatabase._create_sql_schema:  s9     
 5##%&&r8   r>  r  r   r  r6  )r   r  re   rn  rO   r  rf   r  r  )
re   rn  r   r  rO   r  rf   r  r  r  r  )r   r   r   r   r   rn  r   r  rO   r  r   r  r   r   r  r  r  r9  r7  r  )r   r   rO   r  r   r  r  r   )r  r  r  r  r  r   r   r   r   r:  rC  r   r  r   r   r   r   r  r  r   r8   r6   r   r   R
  s    	 	( 
 !!%9@$$
 $ $ 7$ $R ! $!%9@& 	& & & 7& 
)&P   $!%59N/ N/ 	N/
 N/ N/ N/ 3N/ N/ 
N/`? !%!' '
 ' ' 
' 'r8   r   c           	     l    [        US9 nUR                  XX$US9sSSS5        $ ! , (       d  f       g= f)a  
Get the SQL db table schema for the given frame.

Parameters
----------
frame : DataFrame
name : str
    name of SQL table
keys : string or sequence, default: None
    columns to use a primary key
con: ADBC Connection, SQLAlchemy connectable, sqlite3 connection, default: None
    ADBC provides high performance I/O with native type support, where available.
    Using SQLAlchemy makes it possible to use any DB supported by that
    library
    If a DBAPI2 object, only sqlite3 is supported.
dtype : dict of column name to SQL type, default None
    Optional specifying the datatype for columns. The SQL type should
    be a SQLAlchemy type, or a string for sqlite3 fallback connection.
schema: str, default: None
    Optional specifying the schema to be used in creating the table.
r>  )r   rO   r   N)r   r  )r   r   r   r   rO   r   r   s          r6   
get_schemar  N  s4    : 
s	#z,,d - 
 
$	#	#r   )FN)rF   rn  rH   zstr | dict[str, Any] | None)Trc   )re   rn  rf   r  r  r    r6  )re   rn  rO   r  rf   r  )rz   r    rO   r  rf   r  r  r    r   ).......)r   r   r   r  r5   !list[str] | dict[str, str] | Nonerj   r  r   r  rf   DtypeBackend | lib.NoDefaultr  r    )r   r   r   r  r5   r  rj   r  r   r  rf   r	  r  Iterator[DataFrame])r   r   r   r  r   r  re   rn  r5   r  rj   r  r   r  rf   r	  r  r  )r   r  r   $list[Any] | Mapping[str, Any] | Noner5   r  r   r  rO   r  rf   r	  r  r    )r   r  r   r  r5   r  r   r  rO   r  rf   r	  r  r
  )r   r  re   rn  r   r  r5   r  r   r  rO   r  rf   r	  r  r  ).......N)r   r  rj   r  r   r  rf   r	  rO   r  r  r    )r   r  rj   r  r   r  rf   r	  rO   r  r  r
  )r   r  re   rn  rj   r  r   r  rf   r	  rO   r  r  r  )Nr   TNNNNr  )r   r   r   r  r   r  r   rn  r   zIndexLabel | Noner   r  rO   r  r   r  r   r   r  r  )r   r   r   r  r  rn  r5  )r   r  r   rn  r  r   )r   r   r  r  )r   r  )NNNN)r   r   rO   r  r   r  r  r   )kr  
__future__r   abcr   r   
contextlibr   r   r	   r   r
   	functoolsr   r  typingr   r   r   r   r   r   r   rc   rQ   pandas._configr   pandas._libsr   pandas.compat._optionalr   pandas.errorsr   r   pandas.util._exceptionsr   pandas.util._validatorsr   pandas.core.dtypes.commonr   r   pandas.core.dtypes.dtypesr   r   pandas.core.dtypes.missingr   r  r   pandas.core.apir    r!   pandas.core.arraysr"   pandas.core.baser#   pandas.core.commoncorecommonrR  r$   "pandas.core.internals.constructionr%   pandas.core.tools.datetimesr&   collections.abcr'   r(   r   r)   sqlalchemy.sql.expressionr*   r+   pandas._typingr,   r-   r.   r/   r0   r1   r7   rV   rb   r{   r   r   r   r   r   r   r   r   r   table_existsr   r   r   r  r  r  r   r   r  r  r  r  r   r  r   r8   r6   <module>r&     s  
 # 
  	    5  > 5 7 ,  3 )     . C 3
 !
   CGMM$?MD0 5<	* * 3	*
 *J !5< 	  34 !5<
  3 (/F 
 (+58 #25 &	 3   0  
 
 (+58 #25 &	 3   0  
" (,59 $ 25..c?c? c? &	c?
 c? 3c? c? c? 0c? %c?L 
 ),3658 25 &
 1 3   0  
 
 ),3658 25 &
 1 3   0  
" )-3759 !25..e
 &e
 	e

 1e
 3e
 e
 e
 0e
 %e
P 
 ),25! &   0   
 
 ),25! &   0   
$ )- $ 25..!m &m 	m m m 0m m %mh 6<%) !15l

l
 	l

 4l
 l
 #l
 l
 l
 /l
 l
 l
^02 
 """ " 	"JF| FRHc HV( (&z BC@a') a'N[>9 [>B 
0$a$( a$Hy'Y y'~ 
! 

 

  
  
 	 
r8   