Skip to content

Commit 049b37e

Browse files
author
Ilya Gurov
authored
feat: support request priorities (#286)
* feat: support request priorities * use priority constants * Update README.rst * add the test into 1.4 test suite * add missing time module * Update create_test_database.py * fix typo * fix typo * fix tests
1 parent ed4e0a2 commit 049b37e

5 files changed

Lines changed: 70 additions & 4 deletions

File tree

packages/sqlalchemy-spanner/README.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,19 @@ wanted staleness value. For example:
391391
Note that the set option will be dropped when the connection is returned
392392
back to the pool.
393393

394+
Request priority
395+
~~~~~~~~~~~~~~~~~~~~~
396+
In order to use Request Priorities feature in Cloud Spanner, SQLAlchemy provides an ``execution_options`` parameter:
397+
398+
.. code:: python
399+
400+
from google.cloud.spanner_v1 import RequestOptions
401+
402+
with engine.connect().execution_options(
403+
request_priority=RequestOptions.Priority.PRIORITY_MEDIUM
404+
) as connection:
405+
connection.execute(select(["*"], from_obj=table)).fetchall()
406+
394407
DDL and transactions
395408
~~~~~~~~~~~~~~~~~~~~
396409

packages/sqlalchemy-spanner/create_test_database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def create_test_instance():
7070
configs = list(CLIENT.list_instance_configs())
7171
if not USE_EMULATOR:
7272
# Filter out non "us" locations
73-
configs = [config for config in configs if "europe-north1" in config.name]
73+
configs = [config for config in configs if "us-south1" in config.name]
7474

7575
instance_config = configs[0].name
7676
create_time = str(int(time.time()))

packages/sqlalchemy-spanner/google/cloud/sqlalchemy_spanner/sqlalchemy_spanner.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,18 @@ def pre_exec(self):
150150
"""
151151
super(SpannerExecutionContext, self).pre_exec()
152152

153-
read_only = self.execution_options.get("read_only", None)
153+
read_only = self.execution_options.get("read_only")
154154
if read_only is not None:
155155
self._dbapi_connection.connection.read_only = read_only
156156

157-
staleness = self.execution_options.get("staleness", None)
157+
staleness = self.execution_options.get("staleness")
158158
if staleness is not None:
159159
self._dbapi_connection.connection.staleness = staleness
160160

161+
priority = self.execution_options.get("request_priority")
162+
if priority is not None:
163+
self._dbapi_connection.connection.request_priority = priority
164+
161165

162166
class SpannerIdentifierPreparer(IdentifierPreparer):
163167
"""Identifiers compiler.

packages/sqlalchemy-spanner/test/test_suite_13.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import time
2525
from unittest import mock
2626

27+
from google.cloud.spanner_v1 import RequestOptions
28+
2729
import sqlalchemy
2830
from sqlalchemy import create_engine
2931
from sqlalchemy import inspect
@@ -1644,7 +1646,7 @@ def test_offset_only(self):
16441646
list(connection.execute(self._table.select().offset(offset)).fetchall())
16451647

16461648

1647-
class ExecutionOptionsStalenessTest(fixtures.TestBase):
1649+
class ExecutionOptionsTest(fixtures.TestBase):
16481650
"""
16491651
Check that `execution_options()` method correctly
16501652
sets parameters on the underlying DB API connection.
@@ -1680,6 +1682,20 @@ def test_staleness(self):
16801682
with engine.connect() as connection:
16811683
pass
16821684

1685+
def test_request_priority(self):
1686+
PRIORITY = RequestOptions.Priority.PRIORITY_MEDIUM
1687+
with self._engine.connect().execution_options(
1688+
request_priority=PRIORITY
1689+
) as connection:
1690+
connection.execute(select(["*"], from_obj=self._table)).fetchall()
1691+
1692+
with self._engine.connect() as connection:
1693+
assert connection.connection.request_priority is None
1694+
1695+
engine = create_engine("sqlite:///database")
1696+
with engine.connect() as connection:
1697+
pass
1698+
16831699

16841700
class TemporaryTableTest(fixtures.TestBase):
16851701
"""

packages/sqlalchemy-spanner/test/test_suite_14.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121
import pkg_resources
2222
import pytest
2323
import random
24+
import time
2425
from unittest import mock
2526

27+
from google.cloud.spanner_v1 import RequestOptions
28+
2629
import sqlalchemy
2730
from sqlalchemy import create_engine
2831
from sqlalchemy import inspect
@@ -2160,3 +2163,33 @@ def test_round_trip_none_as_json_null(self):
21602163
)
21612164
def test_round_trip_none_as_sql_null(self):
21622165
pass
2166+
2167+
2168+
class ExecutionOptionsRequestPriorotyTest(fixtures.TestBase):
2169+
def setUp(self):
2170+
self._engine = create_engine(get_db_url(), pool_size=1)
2171+
metadata = MetaData(bind=self._engine)
2172+
2173+
self._table = Table(
2174+
"execution_options2",
2175+
metadata,
2176+
Column("opt_id", Integer, primary_key=True),
2177+
Column("opt_name", String(16), nullable=False),
2178+
)
2179+
2180+
metadata.create_all(self._engine)
2181+
time.sleep(1)
2182+
2183+
def test_request_priority(self):
2184+
PRIORITY = RequestOptions.Priority.PRIORITY_MEDIUM
2185+
with self._engine.connect().execution_options(
2186+
request_priority=PRIORITY
2187+
) as connection:
2188+
connection.execute(select(["*"], from_obj=self._table)).fetchall()
2189+
2190+
with self._engine.connect() as connection:
2191+
assert connection.connection.request_priority is None
2192+
2193+
engine = create_engine("sqlite:///database")
2194+
with engine.connect() as connection:
2195+
pass

0 commit comments

Comments
 (0)