Repository: pandas-dev/pandas

Issue:
BUG: SQL get_schema generates incorrect DDL for specific dialect
I'm importing data from an Excel spreadsheet and I'd like to generate a CREATE TABLE statement for PostgreSQL that matches the data I've imported from Excel.

Here's what I've got so far:

``` python
>>> import pandas as pd
>>> from sqlalchemy import create_engine
>>> import psycopg2
>>> basedata = pd.read_excel('mydata.xlsx')
>>> engine = create_engine('postgresql://myusername@localhost:5432/mydb')
>>> pd.io.sql.get_schema(basedata, 'basedata', con=engine)
```

Unfortunately the CREATE TABLE statement generated uses a column type of "DATETIME" that does not exist in PostgreSQL. I suspect that the engine object is being ignored somehow and the DDL I'm getting is for sqlite, not PostgreSQL. However, I can't get pandas to build on my Mac so that I can expand the tests to validate my assumption.



Discussion:
can u post pd.show_versions()

In [3]: pd.show_versions()

## INSTALLED VERSIONS

commit: 9a66dbb301842dbb8de08ba55894bae25e1cefa4
python: 2.7.6.final.0
python-bits: 64
OS: Linux
OS-release: 3.13.0-32-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8

pandas: 0.15.0-62-g9a66dbb
nose: None
Cython: 0.20.1post0
numpy: 1.8.1
scipy: 0.13.3
statsmodels: None
IPython: 1.2.1
sphinx: None
patsy: None
dateutil: 2.2
pytz: 2014.7
bottleneck: None
tables: None
numexpr: None
matplotlib: None
openpyxl: None
xlrd: 0.9.3
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
httplib2: None
apiclient: None
rpy2: None
sqlalchemy: 0.9.8
pymysql: None
psycopg2: 2.5.3 (dt dec pq3 ext)

@hammer This seems indeed a problem with `get_schema`. If you actually write a datetime column to a postgresql database, you get the correct table definition:

```
df = pd.DataFrame({'date':pd.date_range('2012-01-01', periods=10)})
df.to_sql('test_datetime_schema', engine_postgresql, index=False)
```

gives:

```
CREATE TABLE test_datetime_schema
(
  date timestamp without time zone
)
```

Yeah not really inspiring test coverage: https://github.com/pydata/pandas/blob/master/pandas/io/tests/test_sql.py#L642. Only checks for "CREATE" in the string returned by get_schema!

@hammer indeed not very great .. (if you want to try to improve it, always welcome!)


Resolving patch:
diff --git a/pandas/io/sql.py b/pandas/io/sql.py
--- a/pandas/io/sql.py
+++ b/pandas/io/sql.py
@@ -621,7 +621,7 @@ def exists(self):
 
     def sql_schema(self):
         from sqlalchemy.schema import CreateTable
-        return str(CreateTable(self.table))
+        return str(CreateTable(self.table).compile(self.pd_sql.engine))
 
     def _execute_create(self):
         # Inserting table into database, add to MetaData object


Test patch:
diff --git a/pandas/io/tests/test_sql.py b/pandas/io/tests/test_sql.py
--- a/pandas/io/tests/test_sql.py
+++ b/pandas/io/tests/test_sql.py
@@ -1155,6 +1155,19 @@ def test_to_sql_save_index(self):
     def test_transactions(self):
         self._transaction_test()
 
+    def test_get_schema_create_table(self):
+        self._load_test2_data()
+        tbl = 'test_get_schema_create_table'
+        create_sql = sql.get_schema(self.test_frame2, tbl, con=self.conn)
+        blank_test_df = self.test_frame2.iloc[:0]
+
+        self.drop_table(tbl)
+        self.conn.execute(create_sql)
+        returned_df = sql.read_sql_table(tbl, self.conn)
+        tm.assert_frame_equal(returned_df, blank_test_df)
+        self.drop_table(tbl)
+
+
 class TestSQLiteAlchemy(_TestSQLAlchemy):
     """
     Test the sqlalchemy backend against an in-memory sqlite database.