Skip to content

Commit fcad2a5

Browse files
TEST io.sql: sqlite tests to seperate class
One base class for tests with sqlalchemy backend. So test classes for mysql and postgresql don't have to overwrite tests that are different for sqlite.
1 parent 35d61ae commit fcad2a5

File tree

1 file changed

+65
-51
lines changed

1 file changed

+65
-51
lines changed

pandas/io/tests/test_sql.py

+65-51
Original file line numberDiff line numberDiff line change
@@ -425,29 +425,12 @@ def test_date_and_index(self):
425425
"IntDateCol loaded with incorrect type")
426426

427427

428-
class TestSQLAlchemy(PandasSQLTest):
429-
430-
'''
431-
Test the sqlalchemy backend against an in-memory sqlite database.
428+
class _TestSQLAlchemy(PandasSQLTest):
429+
"""
430+
Base class for testing the sqlalchemy backend. Subclasses for specific
431+
database types are created below.
432432
Assume that sqlalchemy takes case of the DB specifics
433-
'''
434-
flavor = 'sqlite'
435-
436-
def connect(self):
437-
return sqlalchemy.create_engine('sqlite:///:memory:')
438-
439-
def setUp(self):
440-
# Skip this test if SQLAlchemy not available
441-
if not SQLALCHEMY_INSTALLED:
442-
raise nose.SkipTest('SQLAlchemy not installed')
443-
444-
self.conn = self.connect()
445-
self.pandasSQL = sql.PandasSQLAlchemy(self.conn)
446-
447-
self._load_iris_data()
448-
self._load_raw_sql()
449-
450-
self._load_test1_data()
433+
"""
451434

452435
def test_read_sql(self):
453436
self._read_sql_iris()
@@ -513,32 +496,31 @@ def test_read_table_absent(self):
513496
ValueError, sql.read_table, "this_doesnt_exist", con=self.conn)
514497

515498
def test_default_type_convertion(self):
516-
""" Test default type conversion"""
517499
df = sql.read_table("types_test_data", self.conn)
518-
self.assertTrue(
519-
issubclass(df.FloatCol.dtype.type, np.floating), "FloatCol loaded with incorrect type")
520-
self.assertTrue(
521-
issubclass(df.IntCol.dtype.type, np.integer), "IntCol loaded with incorrect type")
522-
self.assertTrue(
523-
issubclass(df.BoolCol.dtype.type, np.integer), "BoolCol loaded with incorrect type")
500+
501+
self.assertTrue(issubclass(df.FloatCol.dtype.type, np.floating),
502+
"FloatCol loaded with incorrect type")
503+
self.assertTrue(issubclass(df.IntCol.dtype.type, np.integer),
504+
"IntCol loaded with incorrect type")
505+
self.assertTrue(issubclass(df.BoolCol.dtype.type, np.bool_),
506+
"BoolCol loaded with incorrect type")
524507

525508
# Int column with NA values stays as float
526509
self.assertTrue(issubclass(df.IntColWithNull.dtype.type, np.floating),
527510
"IntColWithNull loaded with incorrect type")
528-
# Non-native Bool column with NA values stays as float
529-
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.floating),
511+
# Bool column with NA values becomes object
512+
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.object),
530513
"BoolColWithNull loaded with incorrect type")
531514

532515
def test_default_date_load(self):
533516
df = sql.read_table("types_test_data", self.conn)
534517

535518
# IMPORTANT - sqlite has no native date type, so shouldn't parse, but
536519
# MySQL SHOULD be converted.
537-
self.assertFalse(
520+
self.assertTrue(
538521
issubclass(df.DateCol.dtype.type, np.datetime64), "DateCol loaded with incorrect type")
539522

540523
def test_date_parsing(self):
541-
""" Test date parsing """
542524
# No Parsing
543525
df = sql.read_table("types_test_data", self.conn)
544526

@@ -573,6 +555,54 @@ def test_date_parsing(self):
573555
"IntDateCol loaded with incorrect type")
574556

575557

558+
class TestSQLAlchemy(_TestSQLAlchemy):
559+
"""
560+
Test the sqlalchemy backend against an in-memory sqlite database.
561+
"""
562+
flavor = 'sqlite'
563+
564+
def connect(self):
565+
return sqlalchemy.create_engine('sqlite:///:memory:')
566+
567+
def setUp(self):
568+
# Skip this test if SQLAlchemy not available
569+
if not SQLALCHEMY_INSTALLED:
570+
raise nose.SkipTest('SQLAlchemy not installed')
571+
572+
self.conn = self.connect()
573+
self.pandasSQL = sql.PandasSQLAlchemy(self.conn)
574+
575+
self._load_iris_data()
576+
self._load_raw_sql()
577+
578+
self._load_test1_data()
579+
580+
def test_default_type_convertion(self):
581+
df = sql.read_table("types_test_data", self.conn)
582+
583+
self.assertTrue(issubclass(df.FloatCol.dtype.type, np.floating),
584+
"FloatCol loaded with incorrect type")
585+
self.assertTrue(issubclass(df.IntCol.dtype.type, np.integer),
586+
"IntCol loaded with incorrect type")
587+
# sqlite has no boolean type, so integer type is returned
588+
self.assertTrue(issubclass(df.BoolCol.dtype.type, np.integer),
589+
"BoolCol loaded with incorrect type")
590+
591+
# Int column with NA values stays as float
592+
self.assertTrue(issubclass(df.IntColWithNull.dtype.type, np.floating),
593+
"IntColWithNull loaded with incorrect type")
594+
# Non-native Bool column with NA values stays as float
595+
self.assertTrue(issubclass(df.BoolColWithNull.dtype.type, np.floating),
596+
"BoolColWithNull loaded with incorrect type")
597+
598+
def test_default_date_load(self):
599+
df = sql.read_table("types_test_data", self.conn)
600+
601+
# IMPORTANT - sqlite has no native date type, so shouldn't parse, but
602+
self.assertFalse(issubclass(df.DateCol.dtype.type, np.datetime64),
603+
"DateCol loaded with incorrect type")
604+
605+
576606
# --- Test SQLITE fallback
577607
class TestSQLite(PandasSQLTest):
578608

@@ -682,7 +712,7 @@ def tearDown(self):
682712
self.conn.close()
683713

684714

685-
class TestMySQLAlchemy(TestSQLAlchemy):
715+
class TestMySQLAlchemy(_TestSQLAlchemy):
686716
flavor = 'mysql'
687717

688718
def connect(self):
@@ -713,16 +743,8 @@ def tearDown(self):
713743
for table in c.fetchall():
714744
self.conn.execute('DROP TABLE %s' % table[0])
715745

716-
def test_default_date_load(self):
717-
df = sql.read_table("types_test_data", self.conn)
718-
719-
# IMPORTANT - sqlite has no native date type, so shouldn't parse,
720-
# but MySQL SHOULD be converted.
721-
self.assertTrue(
722-
issubclass(df.DateCol.dtype.type, np.datetime64), "DateCol loaded with incorrect type")
723746

724-
725-
class TestPostgreSQLAlchemy(TestSQLAlchemy):
747+
class TestPostgreSQLAlchemy(_TestSQLAlchemy):
726748
flavor = 'postgresql'
727749

728750
def connect(self):
@@ -754,14 +776,6 @@ def tearDown(self):
754776
" WHERE table_schema = 'public'")
755777
for table in c.fetchall():
756778
self.conn.execute("DROP TABLE %s" % table[0])
757-
758-
def test_default_date_load(self):
759-
df = sql.read_table("types_test_data", self.conn)
760-
761-
# IMPORTANT - sqlite has no native date type, so shouldn't parse,
762-
# but PostgreSQL SHOULD be converted.
763-
self.assertTrue(issubclass(df.DateCol.dtype.type, np.datetime64),
764-
"DateCol loaded with incorrect type")
765779

766780
if __name__ == '__main__':
767781
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],

0 commit comments

Comments
 (0)