diff --git a/pandas/io/sql.py b/pandas/io/sql.py index a2e66e9ab8e30..c657a925a5eab 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -692,37 +692,25 @@ def insert_data(self): column_names = list(map(str, temp.columns)) ncols = len(column_names) data_list = [None] * ncols - blocks = temp._mgr.blocks - - for b in blocks: - if b.is_datetime: - # return datetime.datetime objects - if b.is_datetimetz: - # GH 9086: Ensure we return datetimes with timezone info - # Need to return 2-D data; DatetimeIndex is 1D - d = b.values.to_pydatetime() - d = np.atleast_2d(d) - else: - # convert to microsecond resolution for datetime.datetime - d = b.values.astype("M8[us]").astype(object) - elif b.is_timedelta: - # numpy converts this to an object array of integers, - # whereas b.astype(object).values would convert to - # object array of Timedeltas - d = b.values.astype(object) + + for i, (_, ser) in enumerate(temp.items()): + vals = ser._values + if vals.dtype.kind == "M": + d = vals.to_pydatetime() + elif vals.dtype.kind == "m": + # store as integers, see GH#6921, GH#7076 + d = vals.view("i8").astype(object) else: - # TODO(2DEA): astype-first can be avoided with 2D EAs - # astype on the block instead of values to ensure we - # get the right shape - d = b.astype(object).values + d = vals.astype(object) + + assert isinstance(d, np.ndarray), type(d) - # replace NaN with None - if b._can_hold_na: + if ser._can_hold_na: + # Note: this will miss timedeltas since they are converted to int mask = isna(d) d[mask] = None - for col_loc, col in zip(b.mgr_locs, d): - data_list[col_loc] = col + data_list[i] = d return column_names, data_list