Skip to content

Commit 17e3aba

Browse files
authored
feat: Support Server-Side Checks for Enums (googleapis#694)
Spanner uses protos for enums. Creating a column like Column("an_enum", Enum("A", "B", "C")) will result in a String column. Setting supports_native_enum to False allows SQLAlchemy to generate check constraints to enforce the enum values if the create_constraint=True flag is passed to the Enum constructor. Fixes: googleapis#686
1 parent bcb8144 commit 17e3aba

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

google/cloud/sqlalchemy_spanner/sqlalchemy_spanner.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,10 +807,15 @@ class SpannerDialect(DefaultDialect):
807807
supports_sequences = True
808808
sequences_optional = False
809809
supports_identity_columns = True
810-
supports_native_enum = True
811810
supports_native_boolean = True
812811
supports_native_decimal = True
813812
supports_statement_cache = True
813+
# Spanner uses protos for enums. Creating a column like
814+
# Column("an_enum", Enum("A", "B", "C")) will result in a String
815+
# column. Setting supports_native_enum to False allows SQLAlchemy
816+
# to generate check constraints to enforce the enum values if the
817+
# create_constraint=True flag is passed to the Enum constructor.
818+
supports_native_enum = False
814819

815820
postfetch_lastrowid = False
816821
insert_returning = True

test/mockserver_tests/test_basics.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
func,
2828
text,
2929
BigInteger,
30+
Enum,
3031
)
3132
from sqlalchemy.orm import Session, DeclarativeBase, Mapped, mapped_column
3233
from sqlalchemy.testing import eq_, is_instance_of
@@ -120,6 +121,7 @@ def test_create_table(self):
120121
metadata,
121122
Column("user_id", Integer, primary_key=True),
122123
Column("user_name", String(16), nullable=False),
124+
Column("status", Enum("a", "b", "cee", create_constraint=True)),
123125
)
124126
metadata.create_all(engine)
125127
requests = self.database_admin_service.requests
@@ -130,7 +132,9 @@ def test_create_table(self):
130132
"CREATE TABLE users (\n"
131133
"\tuser_id INT64 NOT NULL "
132134
"GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), \n"
133-
"\tuser_name STRING(16) NOT NULL\n"
135+
"\tuser_name STRING(16) NOT NULL, \n"
136+
"\tstatus STRING(3), \n"
137+
"\tCHECK (status IN ('a', 'b', 'cee'))\n"
134138
") PRIMARY KEY (user_id)",
135139
requests[0].statements[0],
136140
)

0 commit comments

Comments
 (0)