Skip to content

Commit f7205b5

Browse files
Merge pull request #6875 from Acanthostega/master
BUG: data written with to_sql legacy mode (sqlite/mysql) not persistent GH6846
2 parents 7a4514c + 1c126de commit f7205b5

File tree

2 files changed

+55
-10
lines changed

2 files changed

+55
-10
lines changed

pandas/io/sql.py

+1
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,7 @@ def insert(self):
785785
data.insert(0, self.maybe_asscalar(r[0]))
786786
cur.execute(ins, tuple(data))
787787
cur.close()
788+
self.pd_sql.con.commit()
788789

789790
def _create_table_statement(self):
790791
"Return a CREATE TABLE statement to suit the contents of a DataFrame."

pandas/io/tests/test_sql.py

+54-10
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ def test_to_sql_append(self):
364364
def test_to_sql_series(self):
365365
s = Series(np.arange(5, dtype='int64'), name='series')
366366
sql.to_sql(s, "test_series", self.conn, flavor='sqlite', index=False)
367-
s2 = sql.read_sql("SELECT * FROM test_series", self.conn,
367+
s2 = sql.read_sql("SELECT * FROM test_series", self.conn,
368368
flavor='sqlite')
369369
tm.assert_frame_equal(s.to_frame(), s2)
370370

@@ -473,7 +473,7 @@ def connect(self):
473473

474474
def test_to_sql_index_label(self):
475475
temp_frame = DataFrame({'col1': range(4)})
476-
476+
477477
# no index name, defaults to 'pandas_index'
478478
sql.to_sql(temp_frame, 'test_index_label', self.conn)
479479
frame = sql.read_table('test_index_label', self.conn)
@@ -507,8 +507,52 @@ class TestSQLLegacyApi(_TestSQLApi):
507507
"""
508508
flavor = 'sqlite'
509509

510-
def connect(self):
511-
return sqlite3.connect(':memory:')
510+
def connect(self, database=":memory:"):
511+
return sqlite3.connect(database)
512+
513+
def _load_test2_data(self):
514+
columns = ['index', 'A', 'B']
515+
data = [(
516+
'2000-01-03 00:00:00', 2 ** 31 - 1, -1.987670),
517+
('2000-01-04 00:00:00', -29, -0.0412318367011),
518+
('2000-01-05 00:00:00', 20000, 0.731167677815),
519+
('2000-01-06 00:00:00', -290867, 1.56762092543)]
520+
521+
self.test_frame2 = DataFrame(data, columns=columns)
522+
523+
def test_sql_open_close(self):
524+
"""
525+
Test if the IO in the database still work if the connection
526+
is closed between the writing and reading (as in many real
527+
situations).
528+
"""
529+
530+
self._load_test2_data()
531+
532+
with tm.ensure_clean() as name:
533+
534+
conn = self.connect(name)
535+
536+
sql.to_sql(
537+
self.test_frame2,
538+
"test_frame2_legacy",
539+
conn,
540+
flavor="sqlite",
541+
index=False,
542+
)
543+
544+
conn.close()
545+
conn = self.connect(name)
546+
547+
result = sql.read_sql(
548+
"SELECT * FROM test_frame2_legacy;",
549+
conn,
550+
flavor="sqlite",
551+
)
552+
553+
conn.close()
554+
555+
tm.assert_frame_equal(self.test_frame2, result)
512556

513557

514558
class _TestSQLAlchemy(PandasSQLTest):
@@ -601,7 +645,7 @@ def test_default_type_conversion(self):
601645
self.assertTrue(issubclass(df.IntColWithNull.dtype.type, np.floating),
602646
"IntColWithNull loaded with incorrect type")
603647
# Bool column with NA values becomes object
604-
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.object),
648+
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.object),
605649
"BoolColWithNull loaded with incorrect type")
606650

607651
def test_default_date_load(self):
@@ -696,14 +740,14 @@ def test_default_type_conversion(self):
696740
self.assertTrue(issubclass(df.IntColWithNull.dtype.type, np.floating),
697741
"IntColWithNull loaded with incorrect type")
698742
# Non-native Bool column with NA values stays as float
699-
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.floating),
743+
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.floating),
700744
"BoolColWithNull loaded with incorrect type")
701745

702746
def test_default_date_load(self):
703747
df = sql.read_table("types_test_data", self.conn)
704748

705749
# IMPORTANT - sqlite has no native date type, so shouldn't parse, but
706-
self.assertFalse(issubclass(df.DateCol.dtype.type, np.datetime64),
750+
self.assertFalse(issubclass(df.DateCol.dtype.type, np.datetime64),
707751
"DateCol loaded with incorrect type")
708752

709753

@@ -865,21 +909,21 @@ def test_default_type_conversion(self):
865909
"FloatCol loaded with incorrect type")
866910
self.assertTrue(issubclass(df.IntCol.dtype.type, np.integer),
867911
"IntCol loaded with incorrect type")
868-
# MySQL has no real BOOL type (it's an alias for TINYINT)
912+
# MySQL has no real BOOL type (it's an alias for TINYINT)
869913
self.assertTrue(issubclass(df.BoolCol.dtype.type, np.integer),
870914
"BoolCol loaded with incorrect type")
871915

872916
# Int column with NA values stays as float
873917
self.assertTrue(issubclass(df.IntColWithNull.dtype.type, np.floating),
874918
"IntColWithNull loaded with incorrect type")
875919
# Bool column with NA = int column with NA values => becomes float
876-
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.floating),
920+
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.floating),
877921
"BoolColWithNull loaded with incorrect type")
878922

879923

880924
class TestPostgreSQLAlchemy(_TestSQLAlchemy):
881925
flavor = 'postgresql'
882-
926+
883927
def connect(self):
884928
return sqlalchemy.create_engine(
885929
'postgresql+{driver}://postgres@localhost/pandas_nosetest'.format(driver=self.driver))

0 commit comments

Comments
 (0)