Skip to content

Commit b0372fa

Browse files
BUG: Map pandas integer to optimal SQLAlchemy integer type (GH35076)
1 parent f197ca5 commit b0372fa

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

pandas/io/sql.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,7 @@ def _sqlalchemy_type(self, col):
10971097
DateTime,
10981098
Float,
10991099
Integer,
1100+
SmallInteger,
11001101
Text,
11011102
Time,
11021103
)
@@ -1127,8 +1128,13 @@ def _sqlalchemy_type(self, col):
11271128
else:
11281129
return Float(precision=53)
11291130
elif col_type == "integer":
1130-
if col.dtype == "int32":
1131+
# GH35076 Map pandas integer to optimal SQLAlchemy integer type
1132+
if col.dtype.name.lower() in ("int8", "uint8", "int16"):
1133+
return SmallInteger
1134+
elif col.dtype.name.lower() in ("uint16", "int32"):
11311135
return Integer
1136+
elif col.dtype.name.lower() == "uint64":
1137+
raise ValueError("Unsigned 64 bit integer datatype is not supported")
11321138
else:
11331139
return BigInteger
11341140
elif col_type == "boolean":

pandas/tests/io/test_sql.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,45 @@ def test_sqlalchemy_type_mapping(self):
11391139
# GH 9086: TIMESTAMP is the suggested type for datetimes with timezones
11401140
assert isinstance(table.table.c["time"].type, sqltypes.TIMESTAMP)
11411141

1142+
@pytest.mark.parametrize(
1143+
"integer, expected",
1144+
[
1145+
("int8", "SMALLINT"),
1146+
("Int8", "SMALLINT"),
1147+
("uint8", "SMALLINT"),
1148+
("UInt8", "SMALLINT"),
1149+
("int16", "SMALLINT"),
1150+
("Int16", "SMALLINT"),
1151+
("uint16", "INTEGER"),
1152+
("UInt16", "INTEGER"),
1153+
("int32", "INTEGER"),
1154+
("Int32", "INTEGER"),
1155+
("uint32", "BIGINT"),
1156+
("UInt32", "BIGINT"),
1157+
(int, "BIGINT"),
1158+
("int64", "BIGINT"),
1159+
("Int64", "BIGINT"),
1160+
],
1161+
)
1162+
def test_sqlalchemy_integer_mapping(self, integer, expected):
1163+
# GH35076 Map pandas integer to optimal SQLAlchemy integer type
1164+
df = DataFrame([0, 1], columns=["a"], dtype=integer)
1165+
db = sql.SQLDatabase(self.conn)
1166+
table = sql.SQLTable("test_type", db, frame=df)
1167+
1168+
result = str(table.table.c.a.type)
1169+
assert result == expected
1170+
1171+
@pytest.mark.parametrize("integer", ["uint64", "UInt64"])
1172+
def test_sqlalchemy_integer_overload_mapping(self, integer):
1173+
# GH35076 Map pandas integer to optimal SQLAlchemy integer type
1174+
df = DataFrame([0, 1], columns=["a"], dtype=integer)
1175+
db = sql.SQLDatabase(self.conn)
1176+
with pytest.raises(
1177+
ValueError, match="Unsigned 64 bit integer datatype is not supported"
1178+
):
1179+
sql.SQLTable("test_type", db, frame=df)
1180+
11421181
def test_database_uri_string(self):
11431182

11441183
# Test read_sql and .to_sql method with a database URI (GH10654)

0 commit comments

Comments
 (0)