Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mysql support #2482

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions pandas/io/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ def write_frame(frame, name, con, flavor='sqlite', if_exists='fail', **kwargs):
replace: If table exists, drop it, recreate it, and insert data.
append: If table exists, insert data. Create if does not exist.
"""

if 'append' in kwargs:
import warnings
warnings.warn("append is deprecated, use if_exists instead",
warnings.warn("append is deprecated, use if_exists instead",
FutureWarning)
if kwargs['append']:
if_exists='append'
Expand All @@ -195,7 +195,12 @@ def write_frame(frame, name, con, flavor='sqlite', if_exists='fail', **kwargs):

if create is not None:
cur = con.cursor()
<<<<<<< HEAD
cur.execute(create)
=======
create_table = get_schema(frame, name, flavor)
cur.execute(create_table)
>>>>>>> Restored append keyword with a FutureWarning
cur.close()

cur = con.cursor()
Expand Down Expand Up @@ -241,17 +246,28 @@ def table_exists(name, con, flavor):

def get_sqltype(pytype, flavor):
sqltype = {'mysql': 'VARCHAR (63)',
'sqlite': 'TEXT'}

if issubclass(pytype, np.floating):
'oracle': 'VARCHAR2',
'sqlite': 'TEXT',
'postgresql': 'TEXT'}
if issubclass(pytype, np.number):
sqltype['mysql'] = 'FLOAT'
sqltype['sqlite'] = 'REAL'
<<<<<<< HEAD

if issubclass(pytype, np.integer):
#TODO: Refine integer size.
sqltype['mysql'] = 'BIGINT'
sqltype['sqlite'] = 'INTEGER'

=======
sqltype['postgresql'] = 'NUMBER'
if issubclass(pytype, np.integer):
#TODO: Refine integer size.
sqltype['mysql'] = 'BIGINT'
sqltype['oracle'] = 'PLS_INTEGER'
sqltype['sqlite'] = 'INTEGER'
sqltype['postgresql'] = 'INTEGER'
>>>>>>> Restored append keyword with a FutureWarning
if issubclass(pytype, np.datetime64) or pytype is datetime:
# Caution: np.datetime64 is also a subclass of np.number.
sqltype['mysql'] = 'DATETIME'
Expand All @@ -276,7 +292,10 @@ def get_schema(frame, name, flavor, keys=None):
columns = ',\n '.join('[%s] %s' % x for x in column_types)
else:
columns = ',\n '.join('`%s` %s' % x for x in column_types)
<<<<<<< HEAD

=======
>>>>>>> added test keyword_as_column_names
keystr = ''
if keys is not None:
if isinstance(keys, basestring):
Expand Down
48 changes: 41 additions & 7 deletions pandas/io/tests/test_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,40 @@
bool: lambda x: "'%s'" % x,
}

def format_query(sql, *args):
"""

"""
processed_args = []
for arg in args:
if isinstance(arg, float) and isnull(arg):
arg = None

formatter = _formatters[type(arg)]
processed_args.append(formatter(arg))

return sql % tuple(processed_args)

def _skip_if_no_MySQLdb():
try:
import MySQLdb
except ImportError:
raise nose.SkipTest('MySQLdb not installed, skipping')

from datetime import datetime

_formatters = {
datetime: lambda dt: "'%s'" % date_format(dt),
str: lambda x: "'%s'" % x,
np.str_: lambda x: "'%s'" % x,
unicode: lambda x: "'%s'" % x,
float: lambda x: "%.8f" % x,
int: lambda x: "%s" % x,
type(None): lambda x: "NULL",
np.float64: lambda x: "%.10f" % x,
bool: lambda x: "'%s'" % x,
}

def format_query(sql, *args):
"""

Expand Down Expand Up @@ -219,19 +253,18 @@ def test_keyword_as_column_names(self):
df = DataFrame({'From':np.ones(5)})
sql.write_frame(df, con = self.db, name = 'testkeywords')


class TestMySQL(unittest.TestCase):

_multiprocess_can_split_ = True
def setUp(self):
try:
import MySQLdb
import MySQLdb
except ImportError:
raise nose.SkipTest
try:
self.db = MySQLdb.connect(read_default_group='pandas')
except MySQLdb.Error, e:
raise nose.SkipTest(
"Cannot connect to database. "
"Cannot connect to database. "
"Create a group of connection parameters under the heading "
"[pandas] in your system's mysql default file, "
"typically located at ~/.my.cnf or /etc/.my.cnf. ")
Expand Down Expand Up @@ -262,6 +295,7 @@ def test_write_row_by_row(self):

self.db.commit()

>>>>>>> added mysql nosetests and made them optional
result = sql.read_frame("select * from test", con=self.db)
result.index = frame.index
tm.assert_frame_equal(result, frame)
Expand Down Expand Up @@ -388,7 +422,7 @@ def _check_roundtrip(self, frame):

def test_tquery(self):
try:
import MySQLdb
import MySQLdb
except ImportError:
raise nose.SkipTest
frame = tm.makeTimeDataFrame()
Expand All @@ -413,7 +447,7 @@ def test_tquery(self):

def test_uquery(self):
try:
import MySQLdb
import MySQLdb
except ImportError:
raise nose.SkipTest
frame = tm.makeTimeDataFrame()
Expand Down Expand Up @@ -441,7 +475,7 @@ def test_keyword_as_column_names(self):
'''
_skip_if_no_MySQLdb()
df = DataFrame({'From':np.ones(5)})
sql.write_frame(df, con = self.db, name = 'testkeywords',
sql.write_frame(df, con = self.db, name = 'testkeywords',
if_exists='replace', flavor='mysql')


Expand Down