Skip to content

Commit 6a1305e

Browse files
ENH: add "schema" kwarg to io.sql.get_schema method (#38146)
* Added schema kwarg and test * Added type hinting and marked GH issue in test case * fixed pep8 issues * Fixed sorting on import * move comment * styling * review comment * docstring Co-authored-by: Gregory Livschitz <[email protected]>
1 parent 862cd05 commit 6a1305e

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ Other enhancements
260260
- Added :meth:`~DataFrame.set_flags` for setting table-wide flags on a Series or DataFrame (:issue:`28394`)
261261
- :meth:`DataFrame.applymap` now supports ``na_action`` (:issue:`23803`)
262262
- :class:`Index` with object dtype supports division and multiplication (:issue:`34160`)
263+
- :meth:`io.sql.get_schema` now supports a ``schema`` keyword argument that will add a schema into the create table statement (:issue:`28486`)
263264
- :meth:`DataFrame.explode` and :meth:`Series.explode` now support exploding of sets (:issue:`35614`)
264265
- :meth:`DataFrame.hist` now supports time series (datetime) data (:issue:`32590`)
265266
- :meth:`.Styler.set_table_styles` now allows the direct styling of rows and columns and can be chained (:issue:`35607`)

pandas/io/sql.py

+36-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from datetime import date, datetime, time
88
from functools import partial
99
import re
10-
from typing import Iterator, Optional, Union, overload
10+
from typing import Iterator, List, Optional, Union, overload
1111
import warnings
1212

1313
import numpy as np
@@ -1455,9 +1455,22 @@ def drop_table(self, table_name, schema=None):
14551455
self.get_table(table_name, schema).drop()
14561456
self.meta.clear()
14571457

1458-
def _create_sql_schema(self, frame, table_name, keys=None, dtype=None):
1458+
def _create_sql_schema(
1459+
self,
1460+
frame: DataFrame,
1461+
table_name: str,
1462+
keys: Optional[List[str]] = None,
1463+
dtype: Optional[dict] = None,
1464+
schema: Optional[str] = None,
1465+
):
14591466
table = SQLTable(
1460-
table_name, self, frame=frame, index=False, keys=keys, dtype=dtype
1467+
table_name,
1468+
self,
1469+
frame=frame,
1470+
index=False,
1471+
keys=keys,
1472+
dtype=dtype,
1473+
schema=schema,
14611474
)
14621475
return str(table.sql_schema())
14631476

@@ -1588,9 +1601,13 @@ def _create_table_setup(self):
15881601
create_tbl_stmts.append(
15891602
f"CONSTRAINT {self.name}_pk PRIMARY KEY ({cnames_br})"
15901603
)
1591-
1604+
if self.schema:
1605+
schema_name = self.schema + "."
1606+
else:
1607+
schema_name = ""
15921608
create_stmts = [
15931609
"CREATE TABLE "
1610+
+ schema_name
15941611
+ escape(self.name)
15951612
+ " (\n"
15961613
+ ",\n ".join(create_tbl_stmts)
@@ -1845,14 +1862,20 @@ def drop_table(self, name, schema=None):
18451862
drop_sql = f"DROP TABLE {_get_valid_sqlite_name(name)}"
18461863
self.execute(drop_sql)
18471864

1848-
def _create_sql_schema(self, frame, table_name, keys=None, dtype=None):
1865+
def _create_sql_schema(self, frame, table_name, keys=None, dtype=None, schema=None):
18491866
table = SQLiteTable(
1850-
table_name, self, frame=frame, index=False, keys=keys, dtype=dtype
1867+
table_name,
1868+
self,
1869+
frame=frame,
1870+
index=False,
1871+
keys=keys,
1872+
dtype=dtype,
1873+
schema=schema,
18511874
)
18521875
return str(table.sql_schema())
18531876

18541877

1855-
def get_schema(frame, name, keys=None, con=None, dtype=None):
1878+
def get_schema(frame, name, keys=None, con=None, dtype=None, schema=None):
18561879
"""
18571880
Get the SQL db table schema for the given frame.
18581881
@@ -1870,7 +1893,12 @@ def get_schema(frame, name, keys=None, con=None, dtype=None):
18701893
dtype : dict of column name to SQL type, default None
18711894
Optional specifying the datatype for columns. The SQL type should
18721895
be a SQLAlchemy type, or a string for sqlite3 fallback connection.
1896+
schema: str, default: None
1897+
Optional specifying the schema to be used in creating the table.
18731898
1899+
.. versionadded:: 1.2.0
18741900
"""
18751901
pandas_sql = pandasSQL_builder(con=con)
1876-
return pandas_sql._create_sql_schema(frame, name, keys=keys, dtype=dtype)
1902+
return pandas_sql._create_sql_schema(
1903+
frame, name, keys=keys, dtype=dtype, schema=schema
1904+
)

pandas/tests/io/test_sql.py

+7
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,13 @@ def test_get_schema(self):
865865
create_sql = sql.get_schema(self.test_frame1, "test", con=self.conn)
866866
assert "CREATE" in create_sql
867867

868+
def test_get_schema_with_schema(self):
869+
# GH28486
870+
create_sql = sql.get_schema(
871+
self.test_frame1, "test", con=self.conn, schema="pypi"
872+
)
873+
assert "CREATE TABLE pypi." in create_sql
874+
868875
def test_get_schema_dtypes(self):
869876
float_frame = DataFrame({"a": [1.1, 1.2], "b": [2.1, 2.2]})
870877
dtype = sqlalchemy.Integer if self.mode == "sqlalchemy" else "INTEGER"

0 commit comments

Comments
 (0)