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

Commit 7793b7d

Browse files
author
Ilya Gurov
authored
feat: allow SQLAlchemy 1.4 use (#198)
1 parent fa9747e commit 7793b7d

File tree

11 files changed

+86
-33
lines changed

11 files changed

+86
-33
lines changed

google/cloud/sqlalchemy_spanner/requirements.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def computed_columns(self):
2929
def computed_columns_stored(self):
3030
return exclusions.open()
3131

32+
@property
3233
def sane_rowcount(self):
3334
return exclusions.closed()
3435

google/cloud/sqlalchemy_spanner/sqlalchemy_spanner.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@
4848
@listens_for(Pool, "reset")
4949
def reset_connection(dbapi_conn, connection_record):
5050
"""An event of returning a connection back to a pool."""
51-
dbapi_conn.connection.rollback()
51+
if dbapi_conn.connection.inside_transaction:
52+
dbapi_conn.connection.rollback()
53+
5254
if getattr(dbapi_conn.connection, "staleness", None) is not None:
5355
dbapi_conn.connection.staleness = None
5456

noxfile.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class = StreamHandler
6868
)"""
6969

7070

71-
BLACK_VERSION = "black==19.10b0"
71+
BLACK_VERSION = "black==22.3.0"
7272
BLACK_PATHS = ["google", "test", "noxfile.py", "setup.py", "samples"]
7373
DEFAULT_PYTHON_VERSION = "3.8"
7474

@@ -82,10 +82,15 @@ def lint(session):
8282
"""
8383
session.install("flake8", BLACK_VERSION)
8484
session.run(
85-
"black", "--check", *BLACK_PATHS,
85+
"black",
86+
"--check",
87+
*BLACK_PATHS,
8688
)
8789
session.run(
88-
"flake8", "google", "test", "--max-line-length=88",
90+
"flake8",
91+
"google",
92+
"test",
93+
"--max-line-length=88",
8994
)
9095

9196

@@ -101,7 +106,8 @@ def blacken(session):
101106
"""
102107
session.install(BLACK_VERSION)
103108
session.run(
104-
"black", *BLACK_PATHS,
109+
"black",
110+
*BLACK_PATHS,
105111
)
106112

107113

@@ -128,17 +134,23 @@ def compliance_test_13(session):
128134
)
129135

130136
session.install(
131-
"pytest", "pytest-cov", "pytest-asyncio",
137+
"pytest",
138+
"pytest-cov",
139+
"pytest-asyncio",
132140
)
133141

134142
session.install("mock")
135143
session.install("-e", ".[tracing]")
144+
session.run("pip", "install", "sqlalchemy>=1.1.13,<=1.3.24", "--force-reinstall")
145+
session.run("pip", "install", "pytest==6.2.2", "--force-reinstall")
146+
session.run("pip", "install", "opentelemetry-api<=1.10", "--force-reinstall")
147+
session.run("pip", "install", "opentelemetry-sdk<=1.10", "--force-reinstall")
136148
session.run("python", "create_test_database.py")
137149

138150
session.run(
139151
"py.test",
140152
"--cov=google.cloud.sqlalchemy_spanner",
141-
"--cov=tests",
153+
"--cov=test",
142154
"--cov-append",
143155
"--cov-config=.coveragerc",
144156
"--cov-report=",
@@ -164,7 +176,9 @@ def compliance_test_14(session):
164176
)
165177

166178
session.install(
167-
"pytest", "pytest-cov", "pytest-asyncio",
179+
"pytest",
180+
"pytest-cov",
181+
"pytest-asyncio",
168182
)
169183

170184
session.install("mock")
@@ -176,7 +190,7 @@ def compliance_test_14(session):
176190
session.run(
177191
"py.test",
178192
"--cov=google.cloud.sqlalchemy_spanner",
179-
"--cov=tests",
193+
"--cov=test",
180194
"--cov-append",
181195
"--cov-config=.coveragerc",
182196
"--cov-report=",
@@ -214,7 +228,8 @@ def migration_test(session):
214228
session.run("python", "create_test_database.py")
215229

216230
project = os.getenv(
217-
"GOOGLE_CLOUD_PROJECT", os.getenv("PROJECT_ID", "emulator-test-project"),
231+
"GOOGLE_CLOUD_PROJECT",
232+
os.getenv("PROJECT_ID", "emulator-test-project"),
218233
)
219234
db_url = (
220235
f"spanner+spanner:///projects/{project}/instances/"
@@ -242,7 +257,9 @@ def migration_test(session):
242257
with open(files[0], "r") as f:
243258
script_code = f.read()
244259

245-
script_code = script_code.replace("""def upgrade():\n pass""", UPGRADE_CODE)
260+
script_code = script_code.replace(
261+
"""def upgrade() -> None:\n pass""", UPGRADE_CODE
262+
)
246263
with open(files[0], "w") as f:
247264
f.write(script_code)
248265

samples/conftest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
@pytest.fixture
3434
def db_url():
3535
project = os.getenv(
36-
"GOOGLE_CLOUD_PROJECT", os.getenv("PROJECT_ID", "emulator-test-project"),
36+
"GOOGLE_CLOUD_PROJECT",
37+
os.getenv("PROJECT_ID", "emulator-test-project"),
3738
)
3839
db_url = (
3940
f"spanner:///projects/{project}/instances/"

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
[tool:pytest]
1818
addopts= --tb native -v -r fxX --maxfail=25 -p no:warnings
19-
python_files=test/*test_*.py
19+
python_classes=*Test
2020

2121
[sqla_testing]
2222
requirement_cls=google.cloud.sqlalchemy_spanner.requirements:Requirements

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
name = "sqlalchemy-spanner"
2222
description = "SQLAlchemy dialect integrated into Cloud Spanner database"
2323
dependencies = [
24-
"sqlalchemy>=1.1.13, <=1.3.23",
24+
"sqlalchemy>=1.1.13",
2525
"google-cloud-spanner>=3.12.0",
2626
"alembic",
2727
]

test/_helpers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232

3333

3434
PROJECT = os.getenv(
35-
"GOOGLE_CLOUD_PROJECT", os.getenv("PROJECT_ID", "emulator-test-project"),
35+
"GOOGLE_CLOUD_PROJECT",
36+
os.getenv("PROJECT_ID", "emulator-test-project"),
3637
)
3738
DB_URL = (
3839
f"spanner:///projects/{PROJECT}/instances/"

test/benchmark.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def __init__(self):
154154
self._many_rows = []
155155
self._many_rows2 = []
156156
birth_date = datetime.date(1998, 10, 6)
157-
picture = base64.b64encode(u"123".encode())
157+
picture = base64.b64encode("123".encode())
158158
for num in self._many_rows_ids:
159159
self._many_rows.append(
160160
{
@@ -216,7 +216,9 @@ def __init__(self):
216216
super().__init__()
217217
self._engine = create_engine(
218218
"spanner:///projects/{project}/instances/{instance}/databases/{db}".format(
219-
project=PROJECT, instance=INSTANCE, db=DATABASE,
219+
project=PROJECT,
220+
instance=INSTANCE,
221+
db=DATABASE,
220222
)
221223
)
222224
metadata = MetaData(bind=self._engine)
@@ -260,13 +262,15 @@ def insert_one_row_with_fetch_after(self):
260262
@measure_execution_time
261263
def insert_many_rows(self):
262264
self._conn.execute(
263-
self._table.insert(), self._many_rows,
265+
self._table.insert(),
266+
self._many_rows,
264267
)
265268

266269
@measure_execution_time
267270
def insert_many_rows_with_mutations(self):
268271
self._conn.execute(
269-
self._table.insert(), self._many_rows2,
272+
self._table.insert(),
273+
self._many_rows2,
270274
)
271275

272276
@measure_execution_time

test/test_suite_13.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,10 @@ def _test_get_unique_constraints(self, schema=None):
793793

794794
reflected_metadata = MetaData()
795795
reflected = Table(
796-
"testtbl", reflected_metadata, autoload_with=orig_meta.bind, schema=schema,
796+
"testtbl",
797+
reflected_metadata,
798+
autoload_with=orig_meta.bind,
799+
schema=schema,
797800
)
798801

799802
# test "deduplicates for index" logic. MySQL and Oracle
@@ -1079,7 +1082,9 @@ def test_render_literal_numeric(self):
10791082
Overriding the test to avoid the same failure.
10801083
"""
10811084
self._literal_round_trip(
1082-
Numeric(precision=8, scale=4), [15.7563], [decimal.Decimal("15.7563")],
1085+
Numeric(precision=8, scale=4),
1086+
[15.7563],
1087+
[decimal.Decimal("15.7563")],
10831088
)
10841089
self._literal_round_trip(
10851090
Numeric(precision=8, scale=4),
@@ -1098,7 +1103,9 @@ def test_render_literal_numeric_asfloat(self):
10981103
Overriding the test to avoid the same failure.
10991104
"""
11001105
self._literal_round_trip(
1101-
Numeric(precision=8, scale=4, asdecimal=False), [15.7563], [15.7563],
1106+
Numeric(precision=8, scale=4, asdecimal=False),
1107+
[15.7563],
1108+
[15.7563],
11021109
)
11031110
self._literal_round_trip(
11041111
Numeric(precision=8, scale=4, asdecimal=False),
@@ -1193,7 +1200,9 @@ def test_float_as_decimal(self):
11931200
Overriding the test to avoid the same failure.
11941201
"""
11951202
self._do_test(
1196-
Float(precision=8, asdecimal=True), [15.7563], [decimal.Decimal("15.7563")],
1203+
Float(precision=8, asdecimal=True),
1204+
[15.7563],
1205+
[decimal.Decimal("15.7563")],
11971206
)
11981207

11991208
self._do_test(
@@ -1742,7 +1751,9 @@ def define_tables(cls, metadata):
17421751
if testing.requires.computed_columns_stored.enabled:
17431752
t.append_column(
17441753
Column(
1745-
"computed_stored", Integer, Computed("normal - 42", persisted=True),
1754+
"computed_stored",
1755+
Integer,
1756+
Computed("normal - 42", persisted=True),
17461757
)
17471758
)
17481759
if testing.requires.schemas.enabled:

test/test_suite_14.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,9 @@ def test_reflect_bytes_column_max_len(self):
530530
"""
531531
metadata = MetaData(self.bind)
532532
Table(
533-
"bytes_table", metadata, Column("TestColumn", LargeBinary, nullable=False),
533+
"bytes_table",
534+
metadata,
535+
Column("TestColumn", LargeBinary, nullable=False),
534536
)
535537
metadata.create_all()
536538

@@ -600,7 +602,10 @@ def test_get_unique_constraints(self, metadata, connection, use_schema):
600602

601603
reflected_metadata = MetaData()
602604
reflected = Table(
603-
"testtbl", reflected_metadata, autoload_with=connection, schema=schema,
605+
"testtbl",
606+
reflected_metadata,
607+
autoload_with=connection,
608+
schema=schema,
604609
)
605610

606611
# test "deduplicates for index" logic. MySQL and Oracle
@@ -964,7 +969,9 @@ def test_limit_render_multiple_times(self, connection):
964969
u = union(select(stmt), select(stmt)).subquery().select()
965970

966971
self._assert_result(
967-
connection, u, [(2,)],
972+
connection,
973+
u,
974+
[(2,)],
968975
)
969976

970977

@@ -1939,7 +1946,9 @@ def define_tables(cls, metadata):
19391946
if testing.requires.computed_columns_stored.enabled:
19401947
t.append_column(
19411948
Column(
1942-
"computed_stored", Integer, Computed("normal - 42", persisted=True),
1949+
"computed_stored",
1950+
Integer,
1951+
Computed("normal - 42", persisted=True),
19431952
)
19441953
)
19451954

@@ -1960,11 +1969,17 @@ def test_get_column_returns_persisted_with_schema(self):
19601969
)
19611970
if testing.requires.computed_columns_virtual.enabled:
19621971
self.check_column(
1963-
data, "computed_virtual", "normal/2", False,
1972+
data,
1973+
"computed_virtual",
1974+
"normal/2",
1975+
False,
19641976
)
19651977
if testing.requires.computed_columns_stored.enabled:
19661978
self.check_column(
1967-
data, "computed_stored", "normal-42", True,
1979+
data,
1980+
"computed_stored",
1981+
"normal-42",
1982+
True,
19681983
)
19691984

19701985
@pytest.mark.skip("Default values are not supported.")

0 commit comments

Comments
 (0)