Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Extended DB API parameter syntax to optionally provide parameter types #626

Merged
merged 17 commits into from Apr 29, 2021

Conversation

jimfulton
Copy link
Contributor

Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

Fixes #609 🦕

@jimfulton jimfulton requested review from a team and tswast and removed request for a team April 26, 2021 15:23
@google-cla google-cla bot added the cla: yes This human has signed the Contributor License Agreement. label Apr 26, 2021
@product-auto-label product-auto-label bot added the api: bigquery Issues related to the googleapis/python-bigquery API. label Apr 26, 2021
@tswast tswast added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Apr 26, 2021
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Apr 26, 2021
@jimfulton jimfulton changed the title feat: Extended DB API parameter systax to optionally provide parameter types feat: Extended DB API parameter syntax to optionally provide parameter types Apr 26, 2021
Copy link
Contributor

@plamut plamut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a complete review by any means, just glanced over the PR and the regex pattern caught my eye, gave have two improvement suggestions.

google/cloud/bigquery/dbapi/cursor.py Outdated Show resolved Hide resolved
google/cloud/bigquery/dbapi/cursor.py Outdated Show resolved Hide resolved
@@ -26,9 +26,42 @@

_NUMERIC_SERVER_MIN = decimal.Decimal("-9.9999999999999999999999999999999999999E+28")
_NUMERIC_SERVER_MAX = decimal.Decimal("9.9999999999999999999999999999999999999E+28")
_BIGQUERY_SCALAR_TYPES = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance we can use

class SqlParameterScalarTypes:
or
_SQL_SCALAR_TYPES = frozenset(
instead? I worry this will get out-of-sync (already has, missing GEOGRAPHY, which just encodes as a string)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! I didn't know those existed.

So some questions:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SqlParameterScalarTypes and _SQL_SCALAR_TYPES lack DECIMAL and BIGDECIMAL.
https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#decimal_types
Should I add DECIMAL and BIGDECIMAL?

Good catch! Filed #633 so that we can follow-up and add those.

SqlParameterScalarTypes includes some aliases.
Is that something we want in this context? (If so, I'll lobby for INT. ;))

Those aliases were intended to help folks who first learned BigQuery with "legacy" syntax. https://cloud.google.com/bigquery/data-types I think it's worth allowing the same aliases here in the DB-API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second-thought, I don't know if we want to be adding DECIMAL and BIGDECIMAL as aliases. Let's leave them out of this implementation for now, and we can decide later if we want more aliases beyond those we have for Legacy SQL support.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But they're documented in the standard sql docs.

google/cloud/bigquery/dbapi/_helpers.py Outdated Show resolved Hide resolved
self.execute(operation, parameters)
if seq_of_parameters:
formatted_operation, parameter_types = _format_operation(
operation, seq_of_parameters[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you describe in a comment why we grab just the first one? I guess either we get the types correct on the first go, or we have a problem anyway?

Also it's a niche case, but it's possible that someone could pass in a generator or something for the sequence of parameters. In which case [0] won't work. I think we need to either always loop like we had (and add some logic to only extract the types once) or do some funny business with the low-level iteration function.

I probably should have had a test case with this (generator as parameters) when I documented the allowed type as a Sequence.

Edit: Nevermind, Sequence supports integer-based item access https://docs.python.org/3/glossary.html#term-sequence It's "Iterable" that only supports iteration. We might actually want to support this use case, but probably best to wait until we actually get a customer request for that feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment added.

Copy link
Contributor

@tswast tswast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

One optional suggestion, but I'm okay with solving the type aliases feature at a future date (if ever)

("values('%%(oof:INT64)s, %(foo)s, %(foo)s)", dict(foo="INT64")),
),
(
"values(%(foo:INT64)s, %(foo:INT64)s)",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add some tests that check our aliases, too? (INTEGER -> INT64, for example)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a backend alias for INTEGER, so it's not strictly necessary, but will be if we want to support aliases like DECIMAL in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's included in my latest push.

We do need it if we want to do client-side checks.

google/cloud/bigquery/dbapi/_helpers.py Show resolved Hide resolved
@jimfulton jimfulton added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Apr 28, 2021
@tswast tswast added kokoro:run Add this label to force Kokoro to re-run the tests. kokoro:force-run Add this label to force Kokoro to re-run the tests. and removed kokoro:force-run Add this label to force Kokoro to re-run the tests. kokoro:run Add this label to force Kokoro to re-run the tests. labels Apr 28, 2021
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Apr 28, 2021
Copy link
Contributor

@plamut plamut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, although I mostly focused on the params replacement logic and only glanced over the rest (but didn't see anything obvious to fix).

@jimfulton jimfulton merged commit 8bcf397 into master Apr 29, 2021
@jimfulton jimfulton deleted the riversnake-cursor-types-from-query branch April 29, 2021 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: bigquery Issues related to the googleapis/python-bigquery API. cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None or empty array parameter values aren't handled in the dbapi
4 participants