Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d766d21

Browse filesBrowse files
feat: support UPDATE + JOIN in BigQuery dialect (googleapis#1083)
* feat: support UPDATE JOIN * vendor code from sqlalchemy * remove code and add comments * add vendored folder to path in MANIFEST.in * remove extra code * include third_party in pytest * update MANIFEST.in * add init file * add init file * add pyproject.toml * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * update noxfile and owlbot * lint * fix owlbot * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * undo changes for testing * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * add comments to pyproject.toml --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent 5d58038 commit d766d21
Copy full SHA for d766d21

File tree

15 files changed

+157
-4
lines changed
Filter options

15 files changed

+157
-4
lines changed

‎MANIFEST.in

Copy file name to clipboardExpand all lines: MANIFEST.in
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
# Generated by synthtool. DO NOT EDIT!
1818
include README.rst LICENSE
19-
recursive-include google *.json *.proto py.typed
19+
recursive-include third_party/sqlalchemy_bigquery_vendored *
20+
recursive-include sqlalchemy_bigquery *.json *.proto py.typed
2021
recursive-include tests *
2122
global-exclude *.py[co]
2223
global-exclude __pycache__

‎noxfile.py

Copy file name to clipboardExpand all lines: noxfile.py
+8-1Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,14 @@
3131
FLAKE8_VERSION = "flake8==6.1.0"
3232
BLACK_VERSION = "black[jupyter]==23.7.0"
3333
ISORT_VERSION = "isort==5.11.0"
34-
LINT_PATHS = ["docs", "sqlalchemy_bigquery", "tests", "noxfile.py", "setup.py"]
34+
LINT_PATHS = [
35+
"third_party",
36+
"docs",
37+
"sqlalchemy_bigquery",
38+
"tests",
39+
"noxfile.py",
40+
"setup.py",
41+
]
3542

3643
DEFAULT_PYTHON_VERSION = "3.8"
3744

‎owlbot.py

Copy file name to clipboardExpand all lines: owlbot.py
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""This script is used to synthesize generated parts of this library."""
1616

1717
import pathlib
18+
import re
1819

1920
import synthtool as s
2021
from synthtool import gcp
@@ -76,13 +77,24 @@
7677
"import re\nimport shutil",
7778
)
7879

80+
s.replace(
81+
["noxfile.py"],
82+
"LINT_PATHS = \[",
83+
"LINT_PATHS = [\"third_party\", "
84+
)
7985

8086
s.replace(
8187
["noxfile.py"],
8288
"--cov=google",
8389
"--cov=sqlalchemy_bigquery",
8490
)
8591

92+
s.replace(
93+
["noxfile.py"],
94+
"""os.path.join("tests", "unit"),""",
95+
"""os.path.join("tests", "unit"),
96+
os.path.join("third_party", "sqlalchemy_bigquery_vendored"),""",
97+
)
8698

8799
s.replace(
88100
["noxfile.py"],
@@ -284,6 +296,15 @@ def system_noextras(session):
284296
""",
285297
)
286298

299+
300+
# Make sure build includes all necessary files.
301+
s.replace(
302+
["MANIFEST.in"],
303+
re.escape("recursive-include google"),
304+
"""recursive-include third_party/sqlalchemy_bigquery_vendored *
305+
recursive-include sqlalchemy_bigquery""",
306+
)
307+
287308
# ----------------------------------------------------------------------------
288309
# Samples templates
289310
# ----------------------------------------------------------------------------

‎pyproject.toml

Copy file name to clipboard
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Added so third_party folder is included when running `pip install -e .`
2+
# See PR #1083 for more detail
3+
[build-system]
4+
requires = ["setuptools"]
5+
build-backend = "setuptools.build_meta"

‎setup.py

Copy file name to clipboardExpand all lines: setup.py
+16-1Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import itertools
2323
import os
2424
import re
25+
import setuptools
2526
from setuptools import setup
2627

2728
# Package metadata.
@@ -67,6 +68,16 @@ def readme():
6768

6869
extras["all"] = set(itertools.chain.from_iterable(extras.values()))
6970

71+
packages = [
72+
package
73+
for package in setuptools.find_namespace_packages()
74+
if package.startswith("sqlalchemy_bigquery")
75+
] + [
76+
package
77+
for package in setuptools.find_namespace_packages("third_party")
78+
if package.startswith("sqlalchemy_bigquery_vendored")
79+
]
80+
7081
setup(
7182
name=name,
7283
version=version,
@@ -75,7 +86,11 @@ def readme():
7586
long_description_content_type="text/x-rst",
7687
author="The Sqlalchemy-Bigquery Authors",
7788
author_email="googleapis-packages@google.com",
78-
packages=["sqlalchemy_bigquery"],
89+
package_dir={
90+
"sqlalchemy-bigquery": "sqlalchemy_bigquery",
91+
"sqlalchemy_bigquery_vendored": "third_party/sqlalchemy_bigquery_vendored",
92+
},
93+
packages=packages,
7994
url="https://github.com/googleapis/python-bigquery-sqlalchemy",
8095
keywords=["bigquery", "sqlalchemy"],
8196
classifiers=[

‎sqlalchemy_bigquery/base.py

Copy file name to clipboardExpand all lines: sqlalchemy_bigquery/base.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060

6161
from .parse_url import parse_url
6262
from . import _helpers, _struct, _types
63+
import sqlalchemy_bigquery_vendored.sqlalchemy.postgresql.base as vendored_postgresql
6364

6465
# Illegal characters is intended to be all characters that are not explicitly
6566
# allowed as part of the flexible column names.
@@ -189,7 +190,7 @@ def pre_exec(self):
189190
)
190191

191192

192-
class BigQueryCompiler(_struct.SQLCompiler, SQLCompiler):
193+
class BigQueryCompiler(_struct.SQLCompiler, vendored_postgresql.PGCompiler):
193194
compound_keywords = SQLCompiler.compound_keywords.copy()
194195
compound_keywords[selectable.CompoundSelect.UNION] = "UNION DISTINCT"
195196
compound_keywords[selectable.CompoundSelect.UNION_ALL] = "UNION ALL"

‎tests/unit/test_compiler.py

Copy file name to clipboardExpand all lines: tests/unit/test_compiler.py
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,35 @@ def prepare_implicit_join_base_query(
161161
return q
162162

163163

164+
# Test vendored method update_from_clause()
165+
# from sqlalchemy_bigquery_vendored.sqlalchemy.postgresql.base.PGCompiler
166+
def test_update_from_clause(faux_conn, metadata):
167+
table1 = setup_table(
168+
faux_conn,
169+
"table1",
170+
metadata,
171+
sqlalchemy.Column("foo", sqlalchemy.String),
172+
sqlalchemy.Column("bar", sqlalchemy.Integer),
173+
)
174+
table2 = setup_table(
175+
faux_conn,
176+
"table2",
177+
metadata,
178+
sqlalchemy.Column("foo", sqlalchemy.String),
179+
sqlalchemy.Column("bar", sqlalchemy.Integer),
180+
)
181+
182+
stmt = (
183+
sqlalchemy.update(table1)
184+
.where(table1.c.foo == table2.c.foo)
185+
.where(table2.c.bar == 1)
186+
.values(bar=2)
187+
)
188+
expected_sql = "UPDATE `table1` SET `bar`=%(bar:INT64)s FROM `table2` WHERE `table1`.`foo` = `table2`.`foo` AND `table2`.`bar` = %(bar_1:INT64)s"
189+
found_sql = stmt.compile(faux_conn).string
190+
assert found_sql == expected_sql
191+
192+
164193
@sqlalchemy_before_2_0
165194
def test_no_implicit_join_asterix_for_inner_unnest_before_2_0(faux_conn, metadata):
166195
# See: https://github.com/googleapis/python-bigquery-sqlalchemy/issues/368

‎third_party/__init__.py

Copy file name to clipboardExpand all lines: third_party/__init__.py
Whitespace-only changes.

‎third_party/sqlalchemy_bigquery_vendored/__init__.py

Copy file name to clipboardExpand all lines: third_party/sqlalchemy_bigquery_vendored/__init__.py
Whitespace-only changes.

‎third_party/sqlalchemy_bigquery_vendored/py.typed

Copy file name to clipboardExpand all lines: third_party/sqlalchemy_bigquery_vendored/py.typed
Whitespace-only changes.
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
SQLAlchemy was created by Michael Bayer.
2+
3+
Major contributing authors include:
4+
5+
- Mike Bayer
6+
- Jason Kirtland
7+
- Michael Trier
8+
- Diana Clarke
9+
- Gaetan de Menten
10+
- Lele Gaifax
11+
- Jonathan Ellis
12+
- Gord Thompson
13+
- Federico Caselli
14+
- Philip Jenvey
15+
- Rick Morrison
16+
- Chris Withers
17+
- Ants Aasma
18+
- Sheila Allen
19+
- Paul Johnston
20+
- Tony Locke
21+
- Hajime Nakagami
22+
- Vraj Mohan
23+
- Robert Leftwich
24+
- Taavi Burns
25+
- Jonathan Vanasco
26+
- Jeff Widman
27+
- Scott Dugas
28+
- Dobes Vandermeer
29+
- Ville Skytta
30+
- Rodrigo Menezes
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright 2005-2024 SQLAlchemy authors and contributors <see AUTHORS file>.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the "Software"), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7+
of the Software, and to permit persons to whom the Software is furnished to do
8+
so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# __init__.py
2+
# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors
3+
# <see AUTHORS file>
4+
#
5+
# This module is part of SQLAlchemy and is released under
6+
# the MIT License: https://www.opensource.org/licenses/mit-license.php

‎third_party/sqlalchemy_bigquery_vendored/sqlalchemy/postgresql/__init__.py

Copy file name to clipboardExpand all lines: third_party/sqlalchemy_bigquery_vendored/sqlalchemy/postgresql/__init__.py
Whitespace-only changes.
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# dialects/postgresql/base.py
2+
# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors
3+
# <see AUTHORS file>
4+
#
5+
# This module is part of SQLAlchemy and is released under
6+
# the MIT License: https://www.opensource.org/licenses/mit-license.php
7+
# mypy: ignore-errors
8+
9+
from sqlalchemy.sql import compiler
10+
11+
12+
class PGCompiler(compiler.SQLCompiler):
13+
def update_from_clause(
14+
self, update_stmt, from_table, extra_froms, from_hints, **kw
15+
):
16+
kw["asfrom"] = True
17+
return "FROM " + ", ".join(
18+
t._compiler_dispatch(self, fromhints=from_hints, **kw) for t in extra_froms
19+
)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.