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

race condition in system tests -- table list, then get #105

Copy link
Copy link
Closed
@tswast

Description

@tswast
Issue body actions

https://source.cloud.google.com/results/invocations/ed727aae-0f39-444a-ae80-525b801f19cd/targets/cloud-devrel%2Fclient-libraries%2Fpython%2Fgoogleapis%2Fpython-bigquery-sqlalchemy%2Fpresubmit%2Fpresubmit/log

______________________________ test_tables_list _______________________________

engine = Engine(bigquery://)
engine_using_test_dataset = Engine(bigquery:///test_pybigquery)

    def test_tables_list(engine, engine_using_test_dataset):
>       tables = engine.table_names()

tests/system/test_sqlalchemy_bigquery.py:355:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.nox/system-3-8/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2317: in table_names
    return self.dialect.get_table_names(conn, schema)
pybigquery/sqlalchemy_bigquery.py:592: in get_table_names
    return self._get_table_or_view_names(connection, "TABLE", schema)
pybigquery/sqlalchemy_bigquery.py:395: in _get_table_or_view_names
    for table in tables:
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/page_iterator.py:212: in _items_iter
    for page in self._page_iter(increment=False):
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/page_iterator.py:243: in _page_iter
    page = self._next_page()
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/page_iterator.py:369: in _next_page
    response = self._get_next_page_response()
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/page_iterator.py:418: in _get_next_page_response
    return self.api_request(
.nox/system-3-8/lib/python3.8/site-packages/google/cloud/bigquery/client.py:1330: in api_request
    return self._call_api(
.nox/system-3-8/lib/python3.8/site-packages/google/cloud/bigquery/client.py:640: in _call_api
    return call()
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/retry.py:281: in retry_wrapped_func
    return retry_target(
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/retry.py:184: in retry_target
    return target()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <google.cloud.bigquery._http.Connection object at 0x7fc6a7d07310>
method = 'GET'
path = '/projects/precise-truck-742/datasets/create_table_1617200732845/tables'
query_params = {}, data = None, content_type = None, headers = None
api_base_url = None, api_version = None, expect_json = True
_target_object = None, timeout = None

    def api_request(
        self,
        method,
        path,
        query_params=None,
        data=None,
        content_type=None,
        headers=None,
        api_base_url=None,
        api_version=None,
        expect_json=True,
        _target_object=None,
        timeout=_DEFAULT_TIMEOUT,
    ):
        """Make a request over the HTTP transport to the API.

        You shouldn't need to use this method, but if you plan to
        interact with the API using these primitives, this is the
        correct one to use.

        :type method: str
        :param method: The HTTP method name (ie, ``GET``, ``POST``, etc).
                       Required.

        :type path: str
        :param path: The path to the resource (ie, ``'/b/bucket-name'``).
                     Required.

        :type query_params: dict or list
        :param query_params: A dictionary of keys and values (or list of
                             key-value pairs) to insert into the query
                             string of the URL.

        :type data: str
        :param data: The data to send as the body of the request. Default is
                     the empty string.

        :type content_type: str
        :param content_type: The proper MIME type of the data provided. Default
                             is None.

        :type headers: dict
        :param headers: extra HTTP headers to be sent with the request.

        :type api_base_url: str
        :param api_base_url: The base URL for the API endpoint.
                             Typically you won't have to provide this.
                             Default is the standard API base URL.

        :type api_version: str
        :param api_version: The version of the API to call.  Typically
                            you shouldn't provide this and instead use
                            the default for the library.  Default is the
                            latest API version supported by
                            google-cloud-python.

        :type expect_json: bool
        :param expect_json: If True, this method will try to parse the
                            response as JSON and raise an exception if
                            that cannot be done.  Default is True.

        :type _target_object: :class:`object`
        :param _target_object:
            (Optional) Protected argument to be used by library callers. This
            can allow custom behavior, for example, to defer an HTTP request
            and complete initialization of the object at a later time.

        :type timeout: float or tuple
        :param timeout: (optional) The amount of time, in seconds, to wait
            for the server response.

            Can also be passed as a tuple (connect_timeout, read_timeout).
            See :meth:`requests.Session.request` documentation for details.

        :raises ~google.cloud.exceptions.GoogleCloudError: if the response code
            is not 200 OK.
        :raises ValueError: if the response content type is not JSON.
        :rtype: dict or str
        :returns: The API response payload, either as a raw string or
                  a dictionary if the response is valid JSON.
        """
        url = self.build_api_url(
            path=path,
            query_params=query_params,
            api_base_url=api_base_url,
            api_version=api_version,
        )

        # Making the executive decision that any dictionary
        # data will be sent properly as JSON.
        if data and isinstance(data, dict):
            data = json.dumps(data)
            content_type = "application/json"

        response = self._make_request(
            method=method,
            url=url,
            data=data,
            content_type=content_type,
            headers=headers,
            target_object=_target_object,
            timeout=timeout,
        )

        if not 200 <= response.status_code < 300:
>           raise exceptions.from_http_response(response)
E           google.api_core.exceptions.NotFound: 404 GET https://bigquery.googleapis.com/bigquery/v2/projects/precise-truck-742/datasets/create_table_1617200732845/tables?prettyPrint=false: Not found: Dataset precise-truck-742:create_table_1617200732845
_______________________________ test_view_names ________________________________

inspector = <sqlalchemy.engine.reflection.Inspector object at 0x7fc6a7638850>
inspector_using_test_dataset = <sqlalchemy.engine.reflection.Inspector object at 0x7fc6a76382b0>

    def test_view_names(inspector, inspector_using_test_dataset):
>       view_names = inspector.get_view_names()

tests/system/test_sqlalchemy_bigquery.py:592:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.nox/system-3-8/lib/python3.8/site-packages/sqlalchemy/engine/reflection.py:325: in get_view_names
    return self.dialect.get_view_names(
pybigquery/sqlalchemy_bigquery.py:598: in get_view_names
    return self._get_table_or_view_names(connection, "VIEW", schema)
pybigquery/sqlalchemy_bigquery.py:395: in _get_table_or_view_names
    for table in tables:
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/page_iterator.py:212: in _items_iter
    for page in self._page_iter(increment=False):
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/page_iterator.py:243: in _page_iter
    page = self._next_page()
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/page_iterator.py:369: in _next_page
    response = self._get_next_page_response()
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/page_iterator.py:418: in _get_next_page_response
    return self.api_request(
.nox/system-3-8/lib/python3.8/site-packages/google/cloud/bigquery/client.py:1330: in api_request
    return self._call_api(
.nox/system-3-8/lib/python3.8/site-packages/google/cloud/bigquery/client.py:640: in _call_api
    return call()
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/retry.py:281: in retry_wrapped_func
    return retry_target(
.nox/system-3-8/lib/python3.8/site-packages/google/api_core/retry.py:184: in retry_target
    return target()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <google.cloud.bigquery._http.Connection object at 0x7fc6a7d07310>
method = 'GET'
path = '/projects/precise-truck-742/datasets/bq_system_test_1617200758917/tables'
query_params = {}, data = None, content_type = None, headers = None
api_base_url = None, api_version = None, expect_json = True
_target_object = None, timeout = None

    def api_request(
        self,
        method,
        path,
        query_params=None,
        data=None,
        content_type=None,
        headers=None,
        api_base_url=None,
        api_version=None,
        expect_json=True,
        _target_object=None,
        timeout=_DEFAULT_TIMEOUT,
    ):
        """Make a request over the HTTP transport to the API.

        You shouldn't need to use this method, but if you plan to
        interact with the API using these primitives, this is the
        correct one to use.

        :type method: str
        :param method: The HTTP method name (ie, ``GET``, ``POST``, etc).
                       Required.

        :type path: str
        :param path: The path to the resource (ie, ``'/b/bucket-name'``).
                     Required.

        :type query_params: dict or list
        :param query_params: A dictionary of keys and values (or list of
                             key-value pairs) to insert into the query
                             string of the URL.

        :type data: str
        :param data: The data to send as the body of the request. Default is
                     the empty string.

        :type content_type: str
        :param content_type: The proper MIME type of the data provided. Default
                             is None.

        :type headers: dict
        :param headers: extra HTTP headers to be sent with the request.

        :type api_base_url: str
        :param api_base_url: The base URL for the API endpoint.
                             Typically you won't have to provide this.
                             Default is the standard API base URL.

        :type api_version: str
        :param api_version: The version of the API to call.  Typically
                            you shouldn't provide this and instead use
                            the default for the library.  Default is the
                            latest API version supported by
                            google-cloud-python.

        :type expect_json: bool
        :param expect_json: If True, this method will try to parse the
                            response as JSON and raise an exception if
                            that cannot be done.  Default is True.

        :type _target_object: :class:`object`
        :param _target_object:
            (Optional) Protected argument to be used by library callers. This
            can allow custom behavior, for example, to defer an HTTP request
            and complete initialization of the object at a later time.

        :type timeout: float or tuple
        :param timeout: (optional) The amount of time, in seconds, to wait
            for the server response.

            Can also be passed as a tuple (connect_timeout, read_timeout).
            See :meth:`requests.Session.request` documentation for details.

        :raises ~google.cloud.exceptions.GoogleCloudError: if the response code
            is not 200 OK.
        :raises ValueError: if the response content type is not JSON.
        :rtype: dict or str
        :returns: The API response payload, either as a raw string or
                  a dictionary if the response is valid JSON.
        """
        url = self.build_api_url(
            path=path,
            query_params=query_params,
            api_base_url=api_base_url,
            api_version=api_version,
        )

        # Making the executive decision that any dictionary
        # data will be sent properly as JSON.
        if data and isinstance(data, dict):
            data = json.dumps(data)
            content_type = "application/json"

        response = self._make_request(
            method=method,
            url=url,
            data=data,
            content_type=content_type,
            headers=headers,
            target_object=_target_object,
            timeout=timeout,
        )

        if not 200 <= response.status_code < 300:
>           raise exceptions.from_http_response(response)
E           google.api_core.exceptions.NotFound: 404 GET https://bigquery.googleapis.com/bigquery/v2/projects/precise-truck-742/datasets/bq_system_test_1617200758917/tables?prettyPrint=false: Not found: Dataset precise-truck-742:bq_system_test_1617200758917

.nox/system-3-8/lib/python3.8/site-packages/google/cloud/_http.py:483: NotFound

These tables / datasets belong to other libraries. I think there must a race condition between list and getting additional table details. Also, if all that's required is the table name, the get may be unnecessary.

Metadata

Metadata

Assignees

Labels

api: bigqueryIssues related to the googleapis/python-bigquery-sqlalchemy API.Issues related to the googleapis/python-bigquery-sqlalchemy API.priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

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