diff --git a/doc/source/v0.14.1.txt b/doc/source/v0.14.1.txt index 3159bbfc34e7d..6292868dae669 100644 --- a/doc/source/v0.14.1.txt +++ b/doc/source/v0.14.1.txt @@ -280,3 +280,5 @@ Bug Fixes - Bug in ``pandas.core.strings.str_contains`` does not properly match in a case insensitive fashion when ``regex=False`` and ``case=False`` (:issue:`7505`) - Bug in ``expanding_cov``, ``expanding_corr``, ``rolling_cov``, and ``rolling_corr`` for two arguments with mismatched index (:issue:`7512`) + +- Bug in ``to_sql`` taking the boolean column as text column (:issue:`7678`) \ No newline at end of file diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 252d807d1dc3c..9a479afd86cad 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -733,7 +733,7 @@ def _sqlalchemy_type(self, arr_or_dtype): elif com.is_integer_dtype(arr_or_dtype): # TODO: Refine integer size. return BigInteger - elif com.is_bool(arr_or_dtype): + elif com.is_bool_dtype(arr_or_dtype): return Boolean return Text diff --git a/pandas/io/tests/test_sql.py b/pandas/io/tests/test_sql.py index f3ff84120197a..aa69fb964d947 100644 --- a/pandas/io/tests/test_sql.py +++ b/pandas/io/tests/test_sql.py @@ -191,6 +191,26 @@ def _load_test1_data(self): self.test_frame1 = DataFrame(data, columns=columns) + def _load_test2_data(self): + df = DataFrame(dict(A=[4, 1, 3, 6], + B=['asd', 'gsq', 'ylt', 'jkl'], + C=[1.1, 3.1, 6.9, 5.3], + D=[False, True, True, False], + E=['1990-11-22', '1991-10-26', '1993-11-26', '1995-12-12'])) + df['E'] = to_datetime(df['E']) + + self.test_frame3 = df + + def _load_test3_data(self): + columns = ['index', 'A', 'B'] + data = [( + '2000-01-03 00:00:00', 2 ** 31 - 1, -1.987670), + ('2000-01-04 00:00:00', -29, -0.0412318367011), + ('2000-01-05 00:00:00', 20000, 0.731167677815), + ('2000-01-06 00:00:00', -290867, 1.56762092543)] + + self.test_frame3 = DataFrame(data, columns=columns) + def _load_raw_sql(self): self.drop_table('types_test_data') self._get_exec().execute(SQL_STRINGS['create_test_types'][self.flavor]) @@ -331,6 +351,8 @@ def setUp(self): self.conn = self.connect() self._load_iris_data() self._load_test1_data() + self._load_test2_data() + self._load_test3_data() self._load_raw_sql() def test_read_sql_iris(self): @@ -391,6 +413,13 @@ def test_to_sql_append(self): self.assertEqual( num_rows, num_entries, "not the same number of rows as entries") + def test_to_sql_type_mapping(self): + sql.to_sql(self.test_frame3, 'test_frame5', + self.conn, flavor='sqlite', index=False) + result = sql.read_sql("SELECT * FROM test_frame5", self.conn) + + tm.assert_frame_equal(self.test_frame3, result) + def test_to_sql_series(self): s = Series(np.arange(5, dtype='int64'), name='series') sql.to_sql(s, "test_series", self.conn, flavor='sqlite', index=False) @@ -651,35 +680,23 @@ class TestSQLLegacyApi(_TestSQLApi): def connect(self, database=":memory:"): return sqlite3.connect(database) - def _load_test2_data(self): - columns = ['index', 'A', 'B'] - data = [( - '2000-01-03 00:00:00', 2 ** 31 - 1, -1.987670), - ('2000-01-04 00:00:00', -29, -0.0412318367011), - ('2000-01-05 00:00:00', 20000, 0.731167677815), - ('2000-01-06 00:00:00', -290867, 1.56762092543)] - - self.test_frame2 = DataFrame(data, columns=columns) - def test_sql_open_close(self): # Test if the IO in the database still work if the connection closed # between the writing and reading (as in many real situations). - self._load_test2_data() - with tm.ensure_clean() as name: conn = self.connect(name) - sql.to_sql(self.test_frame2, "test_frame2_legacy", conn, + sql.to_sql(self.test_frame3, "test_frame3_legacy", conn, flavor="sqlite", index=False) conn.close() conn = self.connect(name) - result = sql.read_sql_query("SELECT * FROM test_frame2_legacy;", + result = sql.read_sql_query("SELECT * FROM test_frame3_legacy;", conn) conn.close() - tm.assert_frame_equal(self.test_frame2, result) + tm.assert_frame_equal(self.test_frame3, result) def test_read_sql_delegate(self): iris_frame1 = sql.read_sql_query("SELECT * FROM iris", self.conn)