Skip to content

Commit db2288e

Browse files
FIX sql handling of timedelta64 columns (GH6921)
1 parent aa31fd1 commit db2288e

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
@@ -730,7 +730,10 @@ def _sqlalchemy_type(self, arr_or_dtype):
730730
except:
731731
return DateTime
732732
if com.is_timedelta64_dtype(arr_or_dtype):
733-
return Interval
733+
warnings.warn("the 'timedelta' type is not supported, and will be "
734+
"written as integer values (ns frequency) to the "
735+
"database.", UserWarning)
736+
return Integer
734737
elif com.is_float_dtype(arr_or_dtype):
735738
return Float
736739
elif com.is_integer_dtype(arr_or_dtype):
@@ -973,6 +976,11 @@ def _sql_type_name(self, dtype):
973976
pytype_name = "text"
974977
if issubclass(pytype, np.floating):
975978
pytype_name = "float"
979+
elif com.is_timedelta64_dtype(pytype):
980+
warnings.warn("the 'timedelta' type is not supported, and will be "
981+
"written as integer values (ns frequency) to the "
982+
"database.", UserWarning)
983+
pytype_name = "int"
976984
elif issubclass(pytype, np.integer):
977985
pytype_name = "int"
978986
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:
@@ -480,6 +482,17 @@ def test_date_and_index(self):
480482
self.assertTrue(issubclass(df.IntDateCol.dtype.type, np.datetime64),
481483
"IntDateCol loaded with incorrect type")
482484

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

0 commit comments

Comments
 (0)