Skip to content
This repository was archived by the owner on Mar 13, 2026. It is now read-only.

Commit c876e40

Browse files
committed
test: add system test + fix conformance 1.3 test
1 parent c40f02c commit c876e40

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed

google/cloud/sqlalchemy_spanner/sqlalchemy_spanner.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,9 @@ def get_column_specification(self, column, **kwargs):
410410
colspec += " NOT NULL"
411411

412412
has_identity = (
413-
column.identity is not None and self.dialect.supports_identity_columns
413+
hasattr(column, "identity")
414+
and column.identity is not None
415+
and self.dialect.supports_identity_columns
414416
)
415417
default = self.get_column_default_string(column)
416418

test/mockserver_tests/test_auto_increment.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2024 Google LLC All rights reserved.
1+
# Copyright 2025 Google LLC All rights reserved.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -62,6 +62,65 @@ def test_create_table(self):
6262
requests[0].statements[0],
6363
)
6464

65+
def test_create_auto_increment_table(self):
66+
from test.mockserver_tests.auto_increment_model import Base
67+
68+
add_result(
69+
"""SELECT true
70+
FROM INFORMATION_SCHEMA.TABLES
71+
WHERE TABLE_SCHEMA="" AND TABLE_NAME="singers"
72+
LIMIT 1
73+
""",
74+
ResultSet(),
75+
)
76+
engine = create_engine(
77+
"spanner:///projects/p/instances/i/databases/d",
78+
connect_args={"client": self.client, "pool": FixedSizePool(size=10)},
79+
)
80+
engine.dialect.use_auto_increment = True
81+
Base.metadata.create_all(engine)
82+
requests = self.database_admin_service.requests
83+
eq_(1, len(requests))
84+
is_instance_of(requests[0], UpdateDatabaseDdlRequest)
85+
eq_(1, len(requests[0].statements))
86+
eq_(
87+
"CREATE TABLE singers (\n"
88+
"\tid INT64 NOT NULL AUTO_INCREMENT, \n"
89+
"\tname STRING(MAX) NOT NULL\n"
90+
") PRIMARY KEY (id)",
91+
requests[0].statements[0],
92+
)
93+
94+
def test_create_table_with_specific_sequence_kind(self):
95+
from test.mockserver_tests.auto_increment_model import Base
96+
97+
add_result(
98+
"""SELECT true
99+
FROM INFORMATION_SCHEMA.TABLES
100+
WHERE TABLE_SCHEMA="" AND TABLE_NAME="singers"
101+
LIMIT 1
102+
""",
103+
ResultSet(),
104+
)
105+
engine = create_engine(
106+
"spanner:///projects/p/instances/i/databases/d",
107+
connect_args={"client": self.client, "pool": FixedSizePool(size=10)},
108+
)
109+
engine.dialect.default_sequence_kind = "non_existing_kind"
110+
Base.metadata.create_all(engine)
111+
requests = self.database_admin_service.requests
112+
eq_(1, len(requests))
113+
is_instance_of(requests[0], UpdateDatabaseDdlRequest)
114+
eq_(1, len(requests[0].statements))
115+
eq_(
116+
"CREATE TABLE singers (\n"
117+
"\tid INT64 NOT NULL "
118+
"GENERATED BY DEFAULT AS IDENTITY (non_existing_kind), \n"
119+
"\tname STRING(MAX) NOT NULL\n"
120+
") PRIMARY KEY (id)",
121+
requests[0].statements[0],
122+
)
123+
65124
def test_insert_row(self):
66125
from test.mockserver_tests.auto_increment_model import Singer
67126

test/system/test_basics.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@
2424
MetaData,
2525
Boolean,
2626
BIGINT,
27+
select,
2728
)
2829
from sqlalchemy.orm import Session, DeclarativeBase, Mapped, mapped_column
2930
from sqlalchemy.types import REAL
30-
from sqlalchemy.testing import eq_
31+
from sqlalchemy.testing import eq_, is_true
3132
from sqlalchemy.testing.plugin.plugin_base import fixtures
3233

3334

@@ -50,6 +51,12 @@ def define_tables(cls, metadata):
5051
numbers.c.prime.desc(),
5152
spanner_storing=[numbers.c.alternative_name],
5253
)
54+
Table(
55+
"users",
56+
metadata,
57+
Column("ID", Integer, primary_key=True),
58+
Column("name", String(20)),
59+
)
5360

5461
def test_hello_world(self, connection):
5562
greeting = connection.execute(text("select 'Hello World'"))
@@ -69,7 +76,7 @@ def test_reflect(self, connection):
6976
engine = connection.engine
7077
meta: MetaData = MetaData()
7178
meta.reflect(bind=engine)
72-
eq_(1, len(meta.tables))
79+
eq_(2, len(meta.tables))
7380
table = meta.tables["numbers"]
7481
eq_(5, len(table.columns))
7582
eq_("number", table.columns[0].name)
@@ -127,10 +134,25 @@ class Number(Base):
127134
prime: Mapped[bool] = mapped_column(Boolean)
128135
ln: Mapped[float] = mapped_column(REAL)
129136

137+
class User(Base):
138+
__tablename__ = "users"
139+
ID: Mapped[int] = mapped_column(primary_key=True)
140+
name: Mapped[str] = mapped_column(String(20))
141+
130142
engine = connection.engine
131143
with Session(engine) as session:
132144
number = Number(
133145
number=1, name="One", alternative_name="Uno", prime=False, ln=0.0
134146
)
135147
session.add(number)
136148
session.commit()
149+
150+
with Session(engine) as session:
151+
user = User(name="Test")
152+
session.add(user)
153+
session.commit()
154+
155+
statement = select(User).filter_by(name="Test")
156+
users = session.scalars(statement).all()
157+
eq_(1, len(users))
158+
is_true(users[0].ID > 0)

0 commit comments

Comments
 (0)