o
    -7_K                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlZddlmZ ddl	Z
ddlZdd	lmZ dd
lmZ dd Zdd ZG dd deZdS )zDataFrame client for InfluxDB.    )absolute_import)division)print_function)unicode_literalsN)defaultdict   )InfluxDBClient_escape_tagc                 C   s<   | }| dkr	d}n| dkrd}n| dkrd}|dv sJ |S )Nmmsuusnns)sr   r   r    )time_precisionZunitr   r   </usr/lib/python3/dist-packages/influxdb/_dataframe_client.py_pandas_time_unit   s   r   c                 C   s   |  dd S )Nc                 S   s   t | S )Nr	   )vr   r   r   <lambda>    s    z'_escape_pandas_series.<locals>.<lambda>)applyr   r   r   r   _escape_pandas_series   s   r   c                       s   e Zd ZdZedZ									d fdd	Z									
			d fdd	ZdddZ	e
				dddZ					dddZe
dddZd ddZ  ZS )!DataFrameClienta  DataFrameClient instantiates InfluxDBClient to connect to the backend.

    The ``DataFrameClient`` object holds information necessary to connect
    to InfluxDB. Requests can be made to InfluxDB directly through the client.
    The client reads and writes from pandas DataFrames.
    z1970-01-01 00:00:00.000+00:00Nlinec              
      s   |du rg }|du rg }|	ret tt|t|	 }t|D ]C}||	 }|d |	 }|
dkrC| j|j||  ||||||d}n| j	|j||  |||||d}t
t| j|||||
d qdS |
dkrv| j|||||||d}n| j	||||||d}t
t| j|||||
d dS )	a  Write to multiple time series names.

        :param dataframe: data points in a DataFrame
        :param measurement: name of measurement
        :param tags: dictionary of tags, with string key-values
        :param tag_columns: [Optional, default None] List of data tag names
        :param field_columns: [Options, default None] List of data field names
        :param time_precision: [Optional, default None] Either 's', 'ms', 'u'
            or 'n'.
        :param batch_size: [Optional] Value to write the points in batches
            instead of all at one time. Useful for when doing data dumps from
            one database to another or when doing a massive write operation
        :type batch_size: int
        :param protocol: Protocol for writing data. Either 'line' or 'json'.
        :param numeric_precision: Precision for floating point values.
            Either None, 'full' or some int, where int is the desired decimal
            precision. 'full' preserves full precision for int and float
            datatypes. Defaults to None, which preserves 14-15 significant
            figures for float and all significant figures for int datatypes.
        Nr   r   )measurementglobal_tagsr   tag_columnsfield_columnsnumeric_precision)r   tagsr   r   r    )protocolT)r   r   r   r    r   r!   )intmathZceillenfloatrange_convert_dataframe_to_linesZiloccopy_convert_dataframe_to_jsonsuperr   write_points)self	dataframer   r"   r   r    r   databaseZretention_policyZ
batch_sizer#   r!   Znumber_batchesZbatchstart_indexZ	end_indexpoints	__class__r   r   r-   -   sz    	
	
zDataFrameClient.write_points   TFr   GETc                    sh   t ||||||||
|	d	}tt| j|fi |}|  dr2t|dkr0| j|||dS i S |S )a  
        Query data into a DataFrame.

        .. danger::
            In order to avoid injection vulnerabilities (similar to `SQL
            injection <https://www.owasp.org/index.php/SQL_Injection>`_
            vulnerabilities), do not directly include untrusted data into the
            ``query`` parameter, use ``bind_params`` instead.

        :param query: the actual query string
        :param params: additional parameters for the request, defaults to {}
        :param bind_params: bind parameters for the query:
            any variable in the query written as ``'$var_name'`` will be
            replaced with ``bind_params['var_name']``. Only works in the
            ``WHERE`` clause and takes precedence over ``params['params']``
        :param epoch: response timestamps to be in epoch format either 'h',
            'm', 's', 'ms', 'u', or 'ns',defaults to `None` which is
            RFC3339 UTC format with nanosecond precision
        :param expected_response_code: the expected status code of response,
            defaults to 200
        :param database: database to query, defaults to None
        :param raise_errors: Whether or not to raise exceptions when InfluxDB
            returns errors, defaults to True
        :param chunked: Enable to use chunked responses from InfluxDB.
            With ``chunked`` enabled, one ResultSet is returned per chunk
            containing all results within that chunk
        :param chunk_size: Size of each chunk to tell InfluxDB to use.
        :param dropna: drop columns where all values are missing
        :param data_frame_index: the list of columns that
            are used as DataFrame index
        :returns: the queried data
        :rtype: :class:`~.ResultSet`
        )	paramsbind_paramsepochexpected_response_coderaise_errorschunkedr0   method
chunk_sizeZSELECTr   )data_frame_index)	dictr,   r   querystripupper
startswithr&   _to_dataframe)r.   rA   r7   r8   r9   r:   r0   r;   r<   r>   r=   dropnar?   Z
query_argsresultsr3   r   r   rA      s$   .	zDataFrameClient.queryc           
         s  t t}t|trt| j| fddtt|D S | D ]N\}}|\}}|d u r.|}n
|tt	| f}t
|}	t
|	j|	_|rN|	j|dd n|	jddd |	jjd u rb|	jd|	_d |	j_|| |	 q| D ]\}}t
| }	 r|	jdddd	 |	||< qr|S )
Nc                    s   g | ]} qS r   r   ).0_rF   r   r   
<listcomp>   s    z1DataFrameClient._to_dataframe.<locals>.<listcomp>T)inplacetimeUTCallr   )howaxisrL   )r   list
isinstancemaprE   r(   r&   itemstuplesortedpd	DataFrameto_datetimerM   Z	set_indexindextzinfotz_localizenameappendconcat
sort_indexrF   )
r.   ZrsrF   r?   resultkeydatar^   r"   Zdfr   rJ   r   rE      s2   


zDataFrameClient._to_dataframec                    sX  t | tjstdt| t | jtjs!t | jtjs!td|d ur'|ng }|d ur/|ng }d ur7ni |sGt	t
| jt
|}t | jtjsUt| j| _| jjd u rb| jd| _| jd| _| d} dddd	d
dd|d|s fddt| j| |  D }|S  fddt| j| | d| |  D }|S )N%Must be DataFrame, but type was: {0}.4Must be DataFrame with DatetimeIndex or PeriodIndex.rN   strobjectr        @@    .A    eA   +B   Ņ1Br   r   r   r   r   hc                    sH   g | ] \}\}} | tjtj gtj  t|j d qS ))r   fieldsrM   )replacenpinfnanrF   to_dictint64value)rH   tsrI   rec)r   precision_factorr   r   rK     s    
z>DataFrameClient._convert_dataframe_to_json.<locals>.<listcomp>c              	      sd   g | ].\}}\}} t t| t  |tjtj gtj  t	|j
 d qS ))r   r"   rp   rM   )r@   rR   rU   rq   rr   rs   rt   rF   ru   rv   rw   )rH   rx   tagrI   ry   r   rz   r"   r   r   rK   ,  s    record)rS   rX   rY   	TypeErrorformattyper[   PeriodIndexDatetimeIndexrR   setcolumns
differencerZ   r\   r]   astypegetzipZiterrowsru   )r/   r   r"   r   r    r   r2   r   r|   r   r+      s\   

	

z*DataFrameClient._convert_dataframe_to_jsonc                 C   s  |j dd }t|dkrg S t|tjstdt|t|j	tj
s1t|j	tjs1td|jdd |jD d}t|j}|d u rIg }|d u rOg }|d u rUi }t|r]t|ng }t|rgt|ng }|rw|swt|||  }|st|||  }d	d
ddddd|d	}	t|j	tj
r|j	 jtj|	 tjt}
nt|j	jtj|	 tjt}
|r|r|D ]}|| ||< || q|| }|d}|jd	d}| j||dd}|dd }|jd	d}~n|rddd t |! D }tj||j	d}nd}|| "tj#tj# gtj$}t%|}| j||dd}|jjd & | }d||jd	d    ||jd	d  < d||< |jd	d'dd }~t(|}|| d | d |
 & }|S )NrO   )rP   r   re   rf   c                 S   s   i | ]}|t |qS r   r	   )rH   itemr   r   r   
<dictcomp>Q  s    z?DataFrameClient._convert_dataframe_to_lines.<locals>.<dictcomp>)r   r   ri   rj   rk   rl   rm   rn    )rQ   r{   )datatypec                    s    fdd D S )Nc                    s&   g | ]}|rd  j  d | ndqS ),=r   )r^   )rH   r   r   r   r   rK     s   & zQDataFrameClient._convert_dataframe_to_lines.<locals>.<lambda>.<locals>.<listcomp>r   r   r   r   r   r     s    z=DataFrameClient._convert_dataframe_to_lines.<locals>.<lambda>c                 S   s,   g | ]\}}|d vrd |t|ndqS ))Nr   z,{}={}r   )r   r
   )rH   kr   r   r   r   rK     s    z?DataFrameClient._convert_dataframe_to_lines.<locals>.<listcomp>)r[   fieldr   r   c                 S   s
   |  dS )Nr   )lstrip)xr   r   r   r     s   
  ))rF   r*   r&   rS   rX   rY   r~   r   r   r[   r   r   renamer   ZSeriesrR   isinr   Zto_timestampvaluesr   rr   rv   rg   rZ   r_   Zfillnara   _stringify_dataframer   sumjoinrW   rU   rq   rs   rt   ZisnulltolistrT   r
   )r.   r/   r   r    r   r   r   r!   Zcolumn_seriesrz   rM   r{   Ztag_dfr"   Z
tag_stringZfield_dfZnansrp   r2   r   r   r   r)   ;  s   	






$z+DataFrameClient._convert_dataframe_to_linesr   c                 C   sb  |   } | jdgdj}| jdgdj}|d u r| t} nj|dkrG| jdgdj}| j| j|  }| | t| |< | | t| |< nAt|t	r| jdgdj}| j| j|  }| | 
|| |< |dkr~| | t| |< | | t| |< n
| t} ntd|dkr| |  d	7  < d
| |  d
 | |< n	|dkr| t} | jt| _| S )NZinteger)Zincluderh   ZfullZfloating
   zInvalid numeric precision.r   i"r{   )r*   Zselect_dtypesr   r   rg   r   ZapplymapreprrS   r$   round
ValueErrorr   r   )Zdframer!   r   Zint_columnsZstring_columnsZfloat_columnsZnonfloat_columnsr   r   r   r     sT   



z$DataFrameClient._stringify_dataframer   c                 C   sn   || j   }|dkr|d S |dkr|d S |dkr|S |dkr%|d S |dkr-|d	 S |d
kr5|d S d S )Nro   i  r   <   r   r   ri   r   rj   r   rk   )EPOCHZtotal_seconds)r.   Zdatetimer   Zsecondsr   r   r   _datetime_to_epoch  s   z"DataFrameClient._datetime_to_epoch)	NNNNNNNr   N)NNNr5   NTFr   r6   TN)TN)NNNN)NNNNN)r   r   )__name__
__module____qualname____doc__rX   Z	Timestampr   r-   rA   rE   staticmethodr+   r)   r   r   __classcell__r   r   r3   r   r   #   sR    
e
A L
u3r   )r   Z
__future__r   r   r   r   r%   collectionsr   ZpandasrX   Znumpyrr   Zclientr   Zline_protocolr
   r   r   r   r   r   r   r   <module>   s   