Skip to content

Commit 33c66bf

Browse files
Merge pull request #7076 from jorisvandenbossche/sql-timedelta
FIX sql handling of timedelta64 columns (GH6921)
2 parents cba041e + db2288e commit 33c66bf

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

doc/source/io.rst

+7-2
Original file line numberDiff line numberDiff line change
@@ -809,8 +809,6 @@ two extra parameters:
809809
String value 'infer' can be used to instruct the parser to try detecting
810810
the column specifications from the first 100 rows of the data. Default
811811
behaviour, if not specified, is to infer.
812-
As with regular python slices, you can slice to the end of the line
813-
with ``None``, e.g. ``colspecs = [(0, 1), (1, None)]``.
814812
- ``widths``: A list of field widths which can be used instead of 'colspecs'
815813
if the intervals are contiguous.
816814

@@ -3235,6 +3233,13 @@ the database using :func:`~pandas.DataFrame.to_sql`.
32353233
32363234
data.to_sql('data', engine)
32373235
3236+
.. note::
3237+
3238+
Due to the limited support for timedelta's in the different database
3239+
flavors, columns with type ``timedelta64`` will be written as integer
3240+
values as nanoseconds to the database and a warning will be raised.
3241+
3242+
32383243
Reading Tables
32393244
~~~~~~~~~~~~~~
32403245

pandas/io/sql.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,10 @@ def _sqlalchemy_type(self, arr_or_dtype):
725725
except:
726726
return DateTime
727727
if com.is_timedelta64_dtype(arr_or_dtype):
728-
return Interval
728+
warnings.warn("the 'timedelta' type is not supported, and will be "
729+
"written as integer values (ns frequency) to the "
730+
"database.", UserWarning)
731+
return Integer
729732
elif com.is_float_dtype(arr_or_dtype):
730733
return Float
731734
elif com.is_integer_dtype(arr_or_dtype):
@@ -968,6 +971,11 @@ def _sql_type_name(self, dtype):
968971
pytype_name = "text"
969972
if issubclass(pytype, np.floating):
970973
pytype_name = "float"
974+
elif com.is_timedelta64_dtype(pytype):
975+
warnings.warn("the 'timedelta' type is not supported, and will be "
976+
"written as integer values (ns frequency) to the "
977+
"database.", UserWarning)
978+
pytype_name = "int"
971979
elif issubclass(pytype, np.integer):
972980
pytype_name = "int"
973981
elif issubclass(pytype, np.datetime64) or pytype is datetime:

pandas/io/tests/test_sql.py

+13
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@
2929
from datetime import datetime
3030

3131
from pandas import DataFrame, Series, Index, MultiIndex, isnull
32+
from pandas import to_timedelta
3233
import pandas.compat as compat
3334
from pandas.compat import StringIO, range, lrange
3435
from pandas.core.datetools import format as date_format
3536

3637
import pandas.io.sql as sql
3738
import pandas.util.testing as tm
39+
from pandas import _np_version_under1p7
3840

3941

4042
try:
@@ -475,6 +477,17 @@ def test_date_and_index(self):
475477
self.assertTrue(issubclass(df.IntDateCol.dtype.type, np.datetime64),
476478
"IntDateCol loaded with incorrect type")
477479

480+
def test_timedelta(self):
481+
# see #6921
482+
if _np_version_under1p7:
483+
raise nose.SkipTest("test only valid in numpy >= 1.7")
484+
485+
df = to_timedelta(Series(['00:00:01', '00:00:03'], name='foo')).to_frame()
486+
with tm.assert_produces_warning(UserWarning):
487+
df.to_sql('test_timedelta', self.conn)
488+
result = sql.read_sql_query('SELECT * FROM test_timedelta', self.conn)
489+
tm.assert_series_equal(result['foo'], df['foo'].astype('int64'))
490+
478491
def test_to_sql_index_label(self):
479492
temp_frame = DataFrame({'col1': range(4)})
480493

0 commit comments

Comments
 (0)