Skip to content

Commit e75ea29

Browse files
RahulHPjorisvandenbossche
authored andcommitted
ENH: Allow to_sql to recognize single sql type (GH11886)
1 parent 1cd1026 commit e75ea29

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

doc/source/whatsnew/v0.19.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ Other enhancements
310310
- ``pd.read_html()`` has gained support for the ``decimal`` option (:issue:`12907`)
311311
- A function :func:`union_categorical` has been added for combining categoricals, see :ref:`Unioning Categoricals<categorical.union>` (:issue:`13361`)
312312
- ``Series`` has gained the properties ``.is_monotonic``, ``.is_monotonic_increasing``, ``.is_monotonic_decreasing``, similar to ``Index`` (:issue:`13336`)
313+
- ``DataFrame.to_sql `` now allows a single value as the SQL type for all columns (:issue:`11886`).
313314
- ``Series.append`` now supports the ``ignore_index`` option (:issue:`13677`)
314315
- ``.to_stata()`` and ``StataWriter`` can now write variable labels to Stata dta files using a dictionary to make column names to labels (:issue:`13535`, :issue:`13536`)
315316
- ``.to_stata()`` and ``StataWriter`` will automatically convert ``datetime64[ns]`` columns to Stata format ``%tc``, rather than raising a ``ValueError`` (:issue:`12259`)
@@ -322,7 +323,6 @@ Other enhancements
322323
index=['row1', 'row2'])
323324
df.sort_values(by='row2', axis=1)
324325

325-
326326
.. _whatsnew_0190.api:
327327

328328
API changes

pandas/io/sql.py

+15-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import pandas.lib as lib
1515
from pandas.types.missing import isnull
1616
from pandas.types.dtypes import DatetimeTZDtype
17-
from pandas.types.common import (is_list_like,
17+
from pandas.types.common import (is_list_like, is_dict_like,
1818
is_datetime64tz_dtype)
1919

2020
from pandas.compat import (map, zip, raise_with_traceback,
@@ -448,9 +448,10 @@ def to_sql(frame, name, con, flavor=None, schema=None, if_exists='fail',
448448
chunksize : int, default None
449449
If not None, then rows will be written in batches of this size at a
450450
time. If None, all rows will be written at once.
451-
dtype : dict of column name to SQL type, default None
451+
dtype : single SQLtype or dict of column name to SQL type, default None
452452
Optional specifying the datatype for columns. The SQL type should
453453
be a SQLAlchemy type, or a string for sqlite3 fallback connection.
454+
If all columns are of the same type, one single value can be used.
454455
455456
"""
456457
if if_exists not in ('fail', 'replace', 'append'):
@@ -1121,11 +1122,15 @@ def to_sql(self, frame, name, if_exists='fail', index=True,
11211122
chunksize : int, default None
11221123
If not None, then rows will be written in batches of this size at a
11231124
time. If None, all rows will be written at once.
1124-
dtype : dict of column name to SQL type, default None
1125+
dtype : single type or dict of column name to SQL type, default None
11251126
Optional specifying the datatype for columns. The SQL type should
1126-
be a SQLAlchemy type.
1127+
be a SQLAlchemy type. If all columns are of the same type, one
1128+
single value can be used.
11271129
11281130
"""
1131+
if dtype and not is_dict_like(dtype):
1132+
dtype = {col_name: dtype for col_name in frame}
1133+
11291134
if dtype is not None:
11301135
from sqlalchemy.types import to_instance, TypeEngine
11311136
for col, my_type in dtype.items():
@@ -1473,11 +1478,15 @@ def to_sql(self, frame, name, if_exists='fail', index=True,
14731478
chunksize : int, default None
14741479
If not None, then rows will be written in batches of this
14751480
size at a time. If None, all rows will be written at once.
1476-
dtype : dict of column name to SQL type, default None
1481+
dtype : single type or dict of column name to SQL type, default None
14771482
Optional specifying the datatype for columns. The SQL type should
1478-
be a string.
1483+
be a string. If all columns are of the same type, one single value
1484+
can be used.
14791485
14801486
"""
1487+
if dtype and not is_dict_like(dtype):
1488+
dtype = {col_name: dtype for col_name in frame}
1489+
14811490
if dtype is not None:
14821491
for col, my_type in dtype.items():
14831492
if not isinstance(my_type, str):

pandas/io/tests/test_sql.py

+16
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,15 @@ def test_dtype(self):
15371537
self.assertTrue(isinstance(sqltype, sqlalchemy.String))
15381538
self.assertEqual(sqltype.length, 10)
15391539

1540+
# single dtype
1541+
df.to_sql('single_dtype_test', self.conn, dtype=sqlalchemy.TEXT)
1542+
meta = sqlalchemy.schema.MetaData(bind=self.conn)
1543+
meta.reflect()
1544+
sqltypea = meta.tables['single_dtype_test'].columns['A'].type
1545+
sqltypeb = meta.tables['single_dtype_test'].columns['B'].type
1546+
self.assertTrue(isinstance(sqltypea, sqlalchemy.TEXT))
1547+
self.assertTrue(isinstance(sqltypeb, sqlalchemy.TEXT))
1548+
15401549
def test_notnull_dtype(self):
15411550
cols = {'Bool': Series([True, None]),
15421551
'Date': Series([datetime(2012, 5, 1), None]),
@@ -2006,6 +2015,13 @@ def test_dtype(self):
20062015
self.assertRaises(ValueError, df.to_sql,
20072016
'error', self.conn, dtype={'B': bool})
20082017

2018+
# single dtype
2019+
df.to_sql('single_dtype_test', self.conn, dtype='STRING')
2020+
self.assertEqual(
2021+
self._get_sqlite_column_type('single_dtype_test', 'A'), 'STRING')
2022+
self.assertEqual(
2023+
self._get_sqlite_column_type('single_dtype_test', 'B'), 'STRING')
2024+
20092025
def test_notnull_dtype(self):
20102026
if self.flavor == 'mysql':
20112027
raise nose.SkipTest('Not applicable to MySQL legacy')

0 commit comments

Comments
 (0)