|
98 | 98 | # -- Helper functions |
99 | 99 |
|
100 | 100 |
|
101 | | -def _sa_text_if_string(stmt): |
102 | | - """Wrap plain SQL strings in sqlalchemy.text().""" |
| 101 | +def _sa_text_if_string(stmt: Any) -> Any: |
| 102 | + """ |
| 103 | + Wrap plain SQL strings with sqlalchemy.text() if SQLAlchemy is available. |
| 104 | +
|
| 105 | + Parameters |
| 106 | + ---------- |
| 107 | + stmt : Any |
| 108 | + The SQL statement or object. |
| 109 | +
|
| 110 | + Returns |
| 111 | + ------- |
| 112 | + Any |
| 113 | + `sqlalchemy.sql.elements.TextClause` if wrapping occurred, |
| 114 | + otherwise the original statement. |
| 115 | + """ |
103 | 116 | try: |
104 | | - import sqlalchemy as sa |
105 | | - except Exception: |
| 117 | + import sqlalchemy as sa # lazy import; keep SA optional |
| 118 | + except ImportError: |
106 | 119 | return stmt |
107 | 120 | return sa.text(stmt) if isinstance(stmt, str) else stmt |
108 | 121 |
|
109 | 122 |
|
110 | 123 | def _process_parse_dates_argument(parse_dates): |
| 124 | + |
111 | 125 | """Process parse_dates argument for read_sql functions""" |
112 | 126 | # handle non-list entries for parse_dates gracefully |
113 | 127 | if parse_dates is True or parse_dates is None or parse_dates is False: |
@@ -1826,53 +1840,9 @@ def read_query( |
1826 | 1840 | ) -> DataFrame | Iterator[DataFrame]: |
1827 | 1841 | """ |
1828 | 1842 | Read SQL query into a DataFrame. |
1829 | | -
|
1830 | | - Parameters |
1831 | | - ---------- |
1832 | | - sql : str |
1833 | | - SQL query to be executed. |
1834 | | - index_col : string, optional, default: None |
1835 | | - Column name to use as index for the returned DataFrame object. |
1836 | | - coerce_float : bool, default True |
1837 | | - Attempt to convert values of non-string, non-numeric objects (like |
1838 | | - decimal.Decimal) to floating point, useful for SQL result sets. |
1839 | | - params : list, tuple or dict, optional, default: None |
1840 | | - List of parameters to pass to execute method. The syntax used |
1841 | | - to pass parameters is database driver dependent. Check your |
1842 | | - database driver documentation for which of the five syntax styles, |
1843 | | - described in PEP 249's paramstyle, is supported. |
1844 | | - Eg. for psycopg2, uses %(name)s so use params={'name' : 'value'} |
1845 | | - parse_dates : list or dict, default: None |
1846 | | - - List of column names to parse as dates. |
1847 | | - - Dict of ``{column_name: format string}`` where format string is |
1848 | | - strftime compatible in case of parsing string times, or is one of |
1849 | | - (D, s, ns, ms, us) in case of parsing integer timestamps. |
1850 | | - - Dict of ``{column_name: arg dict}``, where the arg dict |
1851 | | - corresponds to the keyword arguments of |
1852 | | - :func:`pandas.to_datetime` Especially useful with databases |
1853 | | - without native Datetime support, such as SQLite. |
1854 | | - chunksize : int, default None |
1855 | | - If specified, return an iterator where `chunksize` is the number |
1856 | | - of rows to include in each chunk. |
1857 | | - dtype : Type name or dict of columns |
1858 | | - Data type for data or columns. E.g. np.float64 or |
1859 | | - {'a': np.float64, 'b': np.int32, 'c': 'Int64'} |
1860 | | -
|
1861 | | - .. versionadded:: 1.3.0 |
1862 | | -
|
1863 | | - Returns |
1864 | | - ------- |
1865 | | - DataFrame |
1866 | | -
|
1867 | | - See Also |
1868 | | - -------- |
1869 | | - read_sql_table : Read SQL database table into a DataFrame. |
1870 | | - read_sql |
1871 | | -
|
1872 | | -
|
1873 | 1843 | """ |
1874 | | - sql = _sa_text_if_string(sql) |
1875 | | - result = self.execute(sql, params) |
| 1844 | + stmt = _sa_text_if_string(sql) |
| 1845 | + result = self.execute(stmt, params) |
1876 | 1846 | columns = result.keys() |
1877 | 1847 |
|
1878 | 1848 | if chunksize is not None: |
@@ -1901,6 +1871,7 @@ def read_query( |
1901 | 1871 | ) |
1902 | 1872 | return frame |
1903 | 1873 |
|
| 1874 | + |
1904 | 1875 | read_sql = read_query |
1905 | 1876 |
|
1906 | 1877 | def prep_table( |
|
0 commit comments