|
29 | 29 | from datetime import datetime, date, time
|
30 | 30 |
|
31 | 31 | from pandas import DataFrame, Series, Index, MultiIndex, isnull, concat
|
32 |
| -from pandas import date_range, to_datetime, to_timedelta |
| 32 | +from pandas import date_range, to_datetime, to_timedelta, Timestamp |
33 | 33 | import pandas.compat as compat
|
34 | 34 | from pandas.compat import StringIO, range, lrange, string_types
|
35 | 35 | from pandas.core.datetools import format as date_format
|
|
100 | 100 | 'postgresql': """CREATE TABLE types_test_data (
|
101 | 101 | "TextCol" TEXT,
|
102 | 102 | "DateCol" TIMESTAMP,
|
| 103 | + "DateColWithTz" TIMESTAMP WITH TIME ZONE, |
103 | 104 | "IntDateCol" INTEGER,
|
104 | 105 | "FloatCol" DOUBLE PRECISION,
|
105 | 106 | "IntCol" INTEGER,
|
|
109 | 110 | )"""
|
110 | 111 | },
|
111 | 112 | 'insert_test_types': {
|
112 |
| - 'sqlite': """ |
| 113 | + 'sqlite': { |
| 114 | + 'query': """ |
113 | 115 | INSERT INTO types_test_data
|
114 | 116 | VALUES(?, ?, ?, ?, ?, ?, ?, ?)
|
115 | 117 | """,
|
116 |
| - 'mysql': """ |
| 118 | + 'fields': ( |
| 119 | + 'TextCol', 'DateCol', 'IntDateCol', 'FloatCol', |
| 120 | + 'IntCol', 'BoolCol', 'IntColWithNull', 'BoolColWithNull' |
| 121 | + ) |
| 122 | + }, |
| 123 | + 'mysql': { |
| 124 | + 'query': """ |
117 | 125 | INSERT INTO types_test_data
|
118 | 126 | VALUES("%s", %s, %s, %s, %s, %s, %s, %s)
|
119 | 127 | """,
|
120 |
| - 'postgresql': """ |
| 128 | + 'fields': ( |
| 129 | + 'TextCol', 'DateCol', 'IntDateCol', 'FloatCol', |
| 130 | + 'IntCol', 'BoolCol', 'IntColWithNull', 'BoolColWithNull' |
| 131 | + ) |
| 132 | + }, |
| 133 | + 'postgresql': { |
| 134 | + 'query': """ |
121 | 135 | INSERT INTO types_test_data
|
122 |
| - VALUES(%s, %s, %s, %s, %s, %s, %s, %s) |
123 |
| - """ |
| 136 | + VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s) |
| 137 | + """, |
| 138 | + 'fields': ( |
| 139 | + 'TextCol', 'DateCol', 'DateColWithTz', 'IntDateCol', 'FloatCol', |
| 140 | + 'IntCol', 'BoolCol', 'IntColWithNull', 'BoolColWithNull' |
| 141 | + ) |
| 142 | + }, |
124 | 143 | },
|
125 | 144 | 'read_parameters': {
|
126 | 145 | 'sqlite': "SELECT * FROM iris WHERE Name=? AND SepalLength=?",
|
@@ -218,11 +237,36 @@ def _load_raw_sql(self):
|
218 | 237 | self._get_exec().execute(SQL_STRINGS['create_test_types'][self.flavor])
|
219 | 238 | ins = SQL_STRINGS['insert_test_types'][self.flavor]
|
220 | 239 |
|
221 |
| - data = [( |
222 |
| - 'first', '2000-01-03 00:00:00', 535852800, 10.10, 1, False, 1, False), |
223 |
| - ('first', '2000-01-04 00:00:00', 1356998400, 10.10, 1, False, None, None)] |
| 240 | + data = [ |
| 241 | + { |
| 242 | + 'TextCol': 'first', |
| 243 | + 'DateCol': '2000-01-03 00:00:00', |
| 244 | + 'DateColWithTz': '2000-01-01 00:00:00-08:00', |
| 245 | + 'IntDateCol': 535852800, |
| 246 | + 'FloatCol': 10.10, |
| 247 | + 'IntCol': 1, |
| 248 | + 'BoolCol': False, |
| 249 | + 'IntColWithNull': 1, |
| 250 | + 'BoolColWithNull': False, |
| 251 | + }, |
| 252 | + { |
| 253 | + 'TextCol': 'first', |
| 254 | + 'DateCol': '2000-01-04 00:00:00', |
| 255 | + 'DateColWithTz': '2000-06-01 00:00:00-07:00', |
| 256 | + 'IntDateCol': 1356998400, |
| 257 | + 'FloatCol': 10.10, |
| 258 | + 'IntCol': 1, |
| 259 | + 'BoolCol': False, |
| 260 | + 'IntColWithNull': None, |
| 261 | + 'BoolColWithNull': None, |
| 262 | + }, |
| 263 | + ] |
| 264 | + |
224 | 265 | for d in data:
|
225 |
| - self._get_exec().execute(ins, d) |
| 266 | + self._get_exec().execute( |
| 267 | + ins['query'], |
| 268 | + [d[field] for field in ins['fields']] |
| 269 | + ) |
226 | 270 |
|
227 | 271 | def _count_rows(self, table_name):
|
228 | 272 | result = self._get_exec().execute(
|
@@ -1512,6 +1556,19 @@ def test_schema_support(self):
|
1512 | 1556 | res2 = pdsql.read_table('test_schema_other2')
|
1513 | 1557 | tm.assert_frame_equal(res1, res2)
|
1514 | 1558 |
|
| 1559 | + def test_datetime_with_time_zone(self): |
| 1560 | + # Test to see if we read the date column with timezones that |
| 1561 | + # the timezone information is converted to utc and into a |
| 1562 | + # np.datetime64 (GH #7139) |
| 1563 | + df = sql.read_sql_table("types_test_data", self.conn) |
| 1564 | + self.assertTrue(issubclass(df.DateColWithTz.dtype.type, np.datetime64), |
| 1565 | + "DateColWithTz loaded with incorrect type") |
| 1566 | + |
| 1567 | + # "2000-01-01 00:00:00-08:00" should convert to "2000-01-01 08:00:00" |
| 1568 | + self.assertEqual(df.DateColWithTz[0], Timestamp('2000-01-01 08:00:00')) |
| 1569 | + |
| 1570 | + # "2000-06-01 00:00:00-07:00" should convert to "2000-06-01 07:00:00" |
| 1571 | + self.assertEqual(df.DateColWithTz[1], Timestamp('2000-06-01 07:00:00')) |
1515 | 1572 |
|
1516 | 1573 | #------------------------------------------------------------------------------
|
1517 | 1574 | #--- Test Sqlite / MySQL fallback
|
|
0 commit comments