Skip to content

Commit 310cfa7

Browse files
authored
Merge branch 'development-build-v1.11.0.dev2' into grouping-rollup-cube
2 parents 5cfc280 + 0c4cf07 commit 310cfa7

25 files changed

+906
-570
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Maksym Voitko
1919
Maxim Zudilov (mxmzdlv)
2020
Maxime Beauchemin (mistercrunch)
2121
Romain Rigaux
22+
Sharoon Thomas (sharoonthomas)
2223
Sumedh Sakdeo
2324
Tim Swast (tswast)
2425
Vince Broz

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ Older versions of this project were distributed as [pybigquery][0].
1313

1414
[2]: https://pypi.org/project/pybigquery/#history
1515

16+
## [1.11.0.dev2](https://github.com/googleapis/python-bigquery-sqlalchemy/compare/v1.9.0...v1.11.0.dev2) (2024-02-01)
17+
18+
## [1.11.0.dev1](https://github.com/googleapis/python-bigquery-sqlalchemy/compare/v1.9.0...v1.11.0.dev1) (2024-01-30)
19+
20+
21+
### Bug Fixes
22+
23+
* Fix coverage test issues in SQLAlchemy migration ([#987](https://github.com/googleapis/python-bigquery-sqlalchemy/pull/987))
24+
* Cleanup test_sqlalchemy_dialect file for readability ([#1018](https://github.com/googleapis/python-bigquery-sqlalchemy/pull/1018))
25+
26+
## [1.11.0.dev0](https://github.com/googleapis/python-bigquery-sqlalchemy/compare/v1.9.0...v1.11.0.dev0) (2024-01-25)
27+
28+
29+
### Features
30+
31+
* Drop support for SQLAlchemy versions 1.2 and 1.3, maintain support for 1.4 and add support for 2.0 ([#920](https://github.com/googleapis/python-bigquery-sqlalchemy/pull/920))
1632

1733
## [1.9.0](https://github.com/googleapis/python-bigquery-sqlalchemy/compare/v1.8.0...v1.9.0) (2023-12-10)
1834

README.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ In order to use this library, you first need to go through the following steps:
3535
.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html
3636

3737
.. note::
38-
This library is only compatible with SQLAlchemy versions < 2.0.0
38+
This library is a prerelease to gauge compatiblity with SQLAlchemy
39+
versions >= 1.4.16 and < 2.1
3940

4041
Installation
4142
------------
@@ -108,7 +109,8 @@ SQLAlchemy
108109
from sqlalchemy.schema import *
109110
engine = create_engine('bigquery://project')
110111
table = Table('dataset.table', MetaData(bind=engine), autoload=True)
111-
print(select([func.count('*')], from_obj=table).scalar())
112+
print(select([func.count('*')], from_obj=table().scalar())
113+
112114
113115
Project
114116
^^^^^^^
@@ -281,7 +283,7 @@ If you need additional control, you can supply a BigQuery client of your own:
281283
282284
engine = create_engine(
283285
'bigquery://some-project/some-dataset?user_supplied_client=True',
284-
connect_args={'client': custom_bq_client},
286+
connect_args={'client': custom_bq_client},
285287
)
286288
287289

noxfile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ def compliance(session):
369369
session.skip("Compliance tests were not found")
370370

371371
session.install("--pre", "grpcio")
372-
session.install("--pre", "--no-deps", "--upgrade", "sqlalchemy<2.0.0")
372+
session.install("--pre", "--no-deps", "--upgrade", "sqlalchemy>=1.4.16,<2.1")
373373
session.install(
374374
"mock",
375375
"pytest",
@@ -543,7 +543,7 @@ def prerelease_deps(session):
543543

544544
prerel_deps = [
545545
"protobuf",
546-
"sqlalchemy<2.0.0",
546+
"sqlalchemy>=1.4.16,<2.1",
547547
# dependency of grpc
548548
"six",
549549
"googleapis-common-protos",

owlbot.py

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,17 @@
4242
system_test_extras=extras,
4343
system_test_extras_by_python=extras_by_python,
4444
)
45-
s.move(templated_files, excludes=[
46-
# sqlalchemy-bigquery was originally licensed MIT
47-
"LICENSE",
48-
"docs/multiprocessing.rst",
49-
# exclude gh actions as credentials are needed for tests
50-
".github/workflows",
51-
"README.rst",
52-
])
45+
s.move(
46+
templated_files,
47+
excludes=[
48+
# sqlalchemy-bigquery was originally licensed MIT
49+
"LICENSE",
50+
"docs/multiprocessing.rst",
51+
# exclude gh actions as credentials are needed for tests
52+
".github/workflows",
53+
"README.rst",
54+
],
55+
)
5356

5457
# ----------------------------------------------------------------------------
5558
# Fixup files
@@ -59,7 +62,7 @@
5962
[".coveragerc"],
6063
"google/cloud/__init__.py",
6164
"sqlalchemy_bigquery/requirements.py",
62-
)
65+
)
6366

6467
s.replace(
6568
["noxfile.py"],
@@ -75,48 +78,49 @@
7578

7679

7780
s.replace(
78-
["noxfile.py"], "--cov=google", "--cov=sqlalchemy_bigquery",
81+
["noxfile.py"],
82+
"--cov=google",
83+
"--cov=sqlalchemy_bigquery",
7984
)
8085

8186

8287
s.replace(
83-
["noxfile.py"],
88+
["noxfile.py"],
8489
"\+ SYSTEM_TEST_EXTRAS",
8590
"",
8691
)
8792

8893

8994
s.replace(
9095
["noxfile.py"],
91-
'''"protobuf",
92-
# dependency of grpc''',
93-
'''"protobuf",
94-
"sqlalchemy<2.0.0",
95-
# dependency of grpc''',
96+
""""protobuf",
97+
# dependency of grpc""",
98+
""""protobuf",
99+
"sqlalchemy>=1.4.16,<2.1",
100+
# dependency of grpc""",
96101
)
97102

98103

99104
s.replace(
100105
["noxfile.py"],
101106
r"def default\(session\)",
102-
"def default(session, install_extras=True)",
107+
"def default(session, install_extras=True)",
103108
)
104109

105110

106-
107-
108111
def place_before(path, text, *before_text, escape=None):
109112
replacement = "\n".join(before_text) + "\n" + text
110113
if escape:
111114
for c in escape:
112-
text = text.replace(c, '\\' + c)
115+
text = text.replace(c, "\\" + c)
113116
s.replace([path], text, replacement)
114117

118+
115119
place_before(
116120
"noxfile.py",
117121
"SYSTEM_TEST_PYTHON_VERSIONS=",
118122
"",
119-
"# We're using two Python versions to test with sqlalchemy 1.3 and 1.4.",
123+
"# We're using two Python versions to test with sqlalchemy>=1.4.16",
120124
)
121125

122126
place_before(
@@ -126,15 +130,15 @@ def place_before(path, text, *before_text, escape=None):
126130
)
127131

128132

129-
install_logic = '''
133+
install_logic = """
130134
if install_extras and session.python in ["3.11", "3.12"]:
131135
install_target = ".[geography,alembic,tests,bqstorage]"
132136
elif install_extras:
133137
install_target = ".[all]"
134138
else:
135139
install_target = "."
136140
session.install("-e", install_target, "-c", constraints_path)
137-
'''
141+
"""
138142

139143
place_before(
140144
"noxfile.py",
@@ -163,7 +167,7 @@ def compliance(session):
163167
session.skip("Compliance tests were not found")
164168
165169
session.install("--pre", "grpcio")
166-
session.install("--pre", "--no-deps", "--upgrade", "sqlalchemy<2.0.0")
170+
session.install("--pre", "--no-deps", "--upgrade", "sqlalchemy>=1.4.16,<2.1")
167171
session.install(
168172
"mock",
169173
"pytest",
@@ -206,12 +210,11 @@ def compliance(session):
206210
'''
207211

208212
place_before(
209-
"noxfile.py",
210-
"@nox.session(python=DEFAULT_PYTHON_VERSION)\n"
211-
"def cover(session):",
212-
compliance,
213-
escape="()",
214-
)
213+
"noxfile.py",
214+
"@nox.session(python=DEFAULT_PYTHON_VERSION)\n" "def cover(session):",
215+
compliance,
216+
escape="()",
217+
)
215218

216219
s.replace(["noxfile.py"], '"alabaster"', '"alabaster", "geoalchemy2", "shapely"')
217220

@@ -267,11 +270,10 @@ def system_noextras(session):
267270

268271
place_before(
269272
"noxfile.py",
270-
"@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS[-1])\n"
271-
"def compliance(session):",
273+
"@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS[-1])\n" "def compliance(session):",
272274
system_noextras,
273275
escape="()[]",
274-
)
276+
)
275277

276278

277279
# Add DB config for SQLAlchemy dialect test suite.
@@ -288,7 +290,7 @@ def system_noextras(session):
288290
[tool:pytest]
289291
addopts= --tb native -v -r fxX -p no:warnings
290292
python_files=tests/*test_*.py
291-
"""
293+
""",
292294
)
293295

294296
# ----------------------------------------------------------------------------
@@ -299,7 +301,7 @@ def system_noextras(session):
299301
python.py_samples(skip_readmes=True)
300302

301303
s.replace(
302-
["./samples/snippets/noxfile.py"],
304+
["./samples/snippets/noxfile.py"],
303305
"""session.install\("-e", _get_repo_root\(\)\)""",
304306
"""session.install("-e", _get_repo_root())
305307
else:

samples/snippets/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ requests==2.31.0
2828
rsa==4.9
2929
shapely==2.0.2
3030
six==1.16.0
31-
sqlalchemy===1.4.27
31+
sqlalchemy==1.4.16
3232
typing-extensions==4.9.0
3333
urllib3==2.1.0

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ def readme():
9999
# Until this issue is closed
100100
# https://github.com/googleapis/google-cloud-python/issues/10566
101101
"google-auth>=1.25.0,<3.0.0dev", # Work around pip wack.
102-
"google-cloud-bigquery>=2.25.2,<4.0.0dev",
102+
"google-cloud-bigquery>=3.3.6,<4.0.0dev",
103103
"packaging",
104-
"sqlalchemy>=1.2.0,<2.0.0dev",
104+
"sqlalchemy>=1.4.16,<2.1",
105105
],
106106
extras_require=extras,
107107
python_requires=">=3.8, <3.13",

sqlalchemy_bigquery/_struct.py

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,14 @@
1717
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1818
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1919

20-
import packaging.version
2120
import sqlalchemy.sql.default_comparator
2221
import sqlalchemy.sql.sqltypes
2322
import sqlalchemy.types
2423

2524
from . import base
2625

27-
sqlalchemy_1_4_or_more = packaging.version.parse(
28-
sqlalchemy.__version__
29-
) >= packaging.version.parse("1.4")
30-
31-
if sqlalchemy_1_4_or_more:
32-
import sqlalchemy.sql.coercions
33-
import sqlalchemy.sql.roles
26+
import sqlalchemy.sql.coercions
27+
import sqlalchemy.sql.roles
3428

3529

3630
def _get_subtype_col_spec(type_):
@@ -103,34 +97,20 @@ def _setup_getitem(self, name):
10397
def __getattr__(self, name):
10498
if name.lower() in self.expr.type._STRUCT_byname:
10599
return self[name]
100+
else:
101+
raise AttributeError(name)
106102

107103
comparator_factory = Comparator
108104

109105

110-
# In the implementations of _field_index below, we're stealing from
111-
# the JSON type implementation, but the code to steal changed in
112-
# 1.4. :/
113-
114-
if sqlalchemy_1_4_or_more:
115-
116-
def _field_index(self, name, operator):
117-
return sqlalchemy.sql.coercions.expect(
118-
sqlalchemy.sql.roles.BinaryElementRole,
119-
name,
120-
expr=self.expr,
121-
operator=operator,
122-
bindparam_type=sqlalchemy.types.String(),
123-
)
124-
125-
else:
126-
127-
def _field_index(self, name, operator):
128-
return sqlalchemy.sql.default_comparator._check_literal(
129-
self.expr,
130-
operator,
131-
name,
132-
bindparam_type=sqlalchemy.types.String(),
133-
)
106+
def _field_index(self, name, operator):
107+
return sqlalchemy.sql.coercions.expect(
108+
sqlalchemy.sql.roles.BinaryElementRole,
109+
name,
110+
expr=self.expr,
111+
operator=operator,
112+
bindparam_type=sqlalchemy.types.String(),
113+
)
134114

135115

136116
def struct_getitem_op(a, b):

0 commit comments

Comments
 (0)