Skip to content
This repository has been archived by the owner on Aug 4, 2023. It is now read-only.

Add docker entrypoint to ensure db migration on startup #270

Merged
merged 6 commits into from Oct 26, 2021

Conversation

AetherUnbound
Copy link
Contributor

@AetherUnbound AetherUnbound commented Oct 25, 2021

Fixes

Fixes #227 by @AetherUnbound

Description

This PR adds a docker entrypoint for the Airflow container. This ensures that wait_for_db.py and airflow db upgrade are always run, regardless of the command supplied. This means that tests run (or any command run) on a fresh install will have a functional Airflow metastore prior to running.

I added an init entrypoint command, which will create an admin user in addition to the above steps. This is now the default command for development.

just test will now only start up the necessary services, rather than the entire stack, since the webserver doesn't need to be running in order to run the tests.

I also added a help command, which will print the help text in the entrypoint and exit. That functionally serves as internal documentation as well, since most users aren't likely to run the container with dc run webserver help.

Example output

just test from fresh instance
$ just test
docker-compose --file=docker-compose.yml --file=docker-compose.override.yml up -d postgres s3
Creating network "openverse-catalog_default" with the default driver
Creating volume "openverse-catalog_airflow-volume" with default driver
Creating volume "openverse-catalog_postgres-volume" with default driver
Creating openverse-catalog_postgres_1 ... done
Creating openverse-catalog_s3_1       ... done
# The test directory is mounted into the container only during testing
docker-compose --file=docker-compose.yml --file=docker-compose.override.yml run -v /home/aether/git-a8c/openverse-catalog/tests:/usr/local/airflow/tests/ --rm webserver /usr/local/airflow/.local/bin/pytest 
Creating openverse-catalog_webserver_run ... done
########################################################################################################################
                                                  WAITING FOR POSTGRES
########################################################################################################################
2021-10-25 19:01:46,988 - /usr/local/airflow/wait_for_db.py - INFO:  Testing DB connection postgresql+psycopg2://airflow:airflow@postgres:5432/airflow
########################################################################################################################
                                                   MIGRATING DATABASE
########################################################################################################################
[2021-10-25 19:01:48,003] {cli_action_loggers.py:105} WARNING - Failed to log action with (psycopg2.errors.UndefinedTable) relation "log" does not exist
LINE 1: INSERT INTO log (dttm, dag_id, task_id, event, execution_dat...
                    ^

[SQL: INSERT INTO log (dttm, dag_id, task_id, event, execution_date, owner, extra) VALUES (%(dttm)s, %(dag_id)s, %(task_id)s, %(event)s, %(execution_date)s, %(owner)s, %(extra)s) RETURNING log.id]
[parameters: {'dttm': datetime.datetime(2021, 10, 25, 19, 1, 47, 995958, tzinfo=Timezone('UTC')), 'dag_id': None, 'task_id': None, 'event': 'cli_upgradedb', 'execution_date': None, 'owner': 'airflow', 'extra': '{"host_name": "58f8908bc3bb", "full_command": "[\'/usr/local/airflow/.local/bin/airflow\', \'db\', \'upgrade\']"}'}]
(Background on this error at: http://sqlalche.me/e/13/f405)
DB: postgresql+psycopg2://airflow:***@postgres:5432/airflow
[2021-10-25 19:01:48,051] {db.py:692} INFO - Creating tables
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> e3a246e0dc1, current schema
INFO  [alembic.runtime.migration] Running upgrade e3a246e0dc1 -> 1507a7289a2f, create is_encrypted
INFO  [alembic.runtime.migration] Running upgrade 1507a7289a2f -> 13eb55f81627, maintain history for compatibility with earlier migrations
INFO  [alembic.runtime.migration] Running upgrade 13eb55f81627 -> 338e90f54d61, More logging into task_instance
INFO  [alembic.runtime.migration] Running upgrade 338e90f54d61 -> 52d714495f0, job_id indices
INFO  [alembic.runtime.migration] Running upgrade 52d714495f0 -> 502898887f84, Adding extra to Log
INFO  [alembic.runtime.migration] Running upgrade 502898887f84 -> 1b38cef5b76e, add dagrun
INFO  [alembic.runtime.migration] Running upgrade 1b38cef5b76e -> 2e541a1dcfed, task_duration
INFO  [alembic.runtime.migration] Running upgrade 2e541a1dcfed -> 40e67319e3a9, dagrun_config
INFO  [alembic.runtime.migration] Running upgrade 40e67319e3a9 -> 561833c1c74b, add password column to user
INFO  [alembic.runtime.migration] Running upgrade 561833c1c74b -> 4446e08588, dagrun start end
INFO  [alembic.runtime.migration] Running upgrade 4446e08588 -> bbc73705a13e, Add notification_sent column to sla_miss
INFO  [alembic.runtime.migration] Running upgrade bbc73705a13e -> bba5a7cfc896, Add a column to track the encryption state of the 'Extra' field in connection
INFO  [alembic.runtime.migration] Running upgrade bba5a7cfc896 -> 1968acfc09e3, add is_encrypted column to variable table
INFO  [alembic.runtime.migration] Running upgrade 1968acfc09e3 -> 2e82aab8ef20, rename user table
INFO  [alembic.runtime.migration] Running upgrade 2e82aab8ef20 -> 211e584da130, add TI state index
INFO  [alembic.runtime.migration] Running upgrade 211e584da130 -> 64de9cddf6c9, add task fails journal table
INFO  [alembic.runtime.migration] Running upgrade 64de9cddf6c9 -> f2ca10b85618, add dag_stats table
INFO  [alembic.runtime.migration] Running upgrade f2ca10b85618 -> 4addfa1236f1, Add fractional seconds to mysql tables
INFO  [alembic.runtime.migration] Running upgrade 4addfa1236f1 -> 8504051e801b, xcom dag task indices
INFO  [alembic.runtime.migration] Running upgrade 8504051e801b -> 5e7d17757c7a, add pid field to TaskInstance
INFO  [alembic.runtime.migration] Running upgrade 5e7d17757c7a -> 127d2bf2dfa7, Add dag_id/state index on dag_run table
INFO  [alembic.runtime.migration] Running upgrade 127d2bf2dfa7 -> cc1e65623dc7, add max tries column to task instance
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 9, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 15, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 9, 27, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
INFO  [alembic.runtime.migration] Running upgrade cc1e65623dc7 -> bdaa763e6c56, Make xcom value column a large binary
INFO  [alembic.runtime.migration] Running upgrade bdaa763e6c56 -> 947454bf1dff, add ti job_id index
INFO  [alembic.runtime.migration] Running upgrade 947454bf1dff -> d2ae31099d61, Increase text size for MySQL (not relevant for other DBs' text types)
INFO  [alembic.runtime.migration] Running upgrade d2ae31099d61 -> 0e2a74e0fc9f, Add time zone awareness
INFO  [alembic.runtime.migration] Running upgrade d2ae31099d61 -> 33ae817a1ff4, kubernetes_resource_checkpointing
INFO  [alembic.runtime.migration] Running upgrade 33ae817a1ff4 -> 27c6a30d7c24, kubernetes_resource_checkpointing
INFO  [alembic.runtime.migration] Running upgrade 27c6a30d7c24 -> 86770d1215c0, add kubernetes scheduler uniqueness
INFO  [alembic.runtime.migration] Running upgrade 86770d1215c0, 0e2a74e0fc9f -> 05f30312d566, merge heads
INFO  [alembic.runtime.migration] Running upgrade 05f30312d566 -> f23433877c24, fix mysql not null constraint
INFO  [alembic.runtime.migration] Running upgrade f23433877c24 -> 856955da8476, fix sqlite foreign key
INFO  [alembic.runtime.migration] Running upgrade 856955da8476 -> 9635ae0956e7, index-faskfail
INFO  [alembic.runtime.migration] Running upgrade 9635ae0956e7 -> dd25f486b8ea, add idx_log_dag
INFO  [alembic.runtime.migration] Running upgrade dd25f486b8ea -> bf00311e1990, add index to taskinstance
INFO  [alembic.runtime.migration] Running upgrade 9635ae0956e7 -> 0a2a5b66e19d, add task_reschedule table
INFO  [alembic.runtime.migration] Running upgrade 0a2a5b66e19d, bf00311e1990 -> 03bc53e68815, merge_heads_2
INFO  [alembic.runtime.migration] Running upgrade 03bc53e68815 -> 41f5f12752f8, add superuser field
INFO  [alembic.runtime.migration] Running upgrade 41f5f12752f8 -> c8ffec048a3b, add fields to dag
INFO  [alembic.runtime.migration] Running upgrade c8ffec048a3b -> dd4ecb8fbee3, Add schedule interval to dag
INFO  [alembic.runtime.migration] Running upgrade dd4ecb8fbee3 -> 939bb1e647c8, task reschedule fk on cascade delete
INFO  [alembic.runtime.migration] Running upgrade 939bb1e647c8 -> 6e96a59344a4, Make TaskInstance.pool not nullable
INFO  [alembic.runtime.migration] Running upgrade 6e96a59344a4 -> d38e04c12aa2, add serialized_dag table
INFO  [alembic.runtime.migration] Running upgrade d38e04c12aa2 -> b3b105409875, add root_dag_id to DAG
INFO  [alembic.runtime.migration] Running upgrade 6e96a59344a4 -> 74effc47d867, change datetime to datetime2(6) on MSSQL tables
INFO  [alembic.runtime.migration] Running upgrade 939bb1e647c8 -> 004c1210f153, increase queue name size limit
INFO  [alembic.runtime.migration] Running upgrade c8ffec048a3b -> a56c9515abdc, Remove dag_stat table
INFO  [alembic.runtime.migration] Running upgrade a56c9515abdc, 004c1210f153, 74effc47d867, b3b105409875 -> 08364691d074, Merge the four heads back together
INFO  [alembic.runtime.migration] Running upgrade 08364691d074 -> fe461863935f, increase_length_for_connection_password
INFO  [alembic.runtime.migration] Running upgrade fe461863935f -> 7939bcff74ba, Add DagTags table
INFO  [alembic.runtime.migration] Running upgrade 7939bcff74ba -> a4c2fd67d16b, add pool_slots field to task_instance
INFO  [alembic.runtime.migration] Running upgrade a4c2fd67d16b -> 852ae6c715af, Add RenderedTaskInstanceFields table
INFO  [alembic.runtime.migration] Running upgrade 852ae6c715af -> 952da73b5eff, add dag_code table
INFO  [alembic.runtime.migration] Running upgrade 952da73b5eff -> a66efa278eea, Add Precision to execution_date in RenderedTaskInstanceFields table
INFO  [alembic.runtime.migration] Running upgrade a66efa278eea -> da3f683c3a5a, Add dag_hash Column to serialized_dag table
INFO  [alembic.runtime.migration] Running upgrade da3f683c3a5a -> 92c57b58940d, Create FAB Tables
INFO  [alembic.runtime.migration] Running upgrade 92c57b58940d -> 03afc6b6f902, Increase length of FAB ab_view_menu.name column
INFO  [alembic.runtime.migration] Running upgrade 03afc6b6f902 -> cf5dc11e79ad, drop_user_and_chart
INFO  [alembic.runtime.migration] Running upgrade cf5dc11e79ad -> bbf4a7ad0465, Remove id column from xcom
INFO  [alembic.runtime.migration] Running upgrade bbf4a7ad0465 -> b25a55525161, Increase length of pool name
INFO  [alembic.runtime.migration] Running upgrade b25a55525161 -> 3c20cacc0044, Add DagRun run_type
INFO  [alembic.runtime.migration] Running upgrade 3c20cacc0044 -> 8f966b9c467a, Set conn_type as non-nullable
INFO  [alembic.runtime.migration] Running upgrade 8f966b9c467a -> 8d48763f6d53, add unique constraint to conn_id
INFO  [alembic.runtime.migration] Running upgrade 8d48763f6d53 -> e38be357a868, Add sensor_instance table
INFO  [alembic.runtime.migration] Running upgrade e38be357a868 -> b247b1e3d1ed, Add queued by Job ID to TI
INFO  [alembic.runtime.migration] Running upgrade b247b1e3d1ed -> e1a11ece99cc, Add external executor ID to TI
INFO  [alembic.runtime.migration] Running upgrade e1a11ece99cc -> bef4f3d11e8b, Drop KubeResourceVersion and KubeWorkerId
INFO  [alembic.runtime.migration] Running upgrade bef4f3d11e8b -> 98271e7606e2, Add scheduling_decision to DagRun and DAG
INFO  [alembic.runtime.migration] Running upgrade 98271e7606e2 -> 52d53670a240, fix_mssql_exec_date_rendered_task_instance_fields_for_MSSQL
INFO  [alembic.runtime.migration] Running upgrade 52d53670a240 -> 364159666cbd, Add creating_job_id to DagRun table
INFO  [alembic.runtime.migration] Running upgrade 364159666cbd -> 45ba3f1493b9, add-k8s-yaml-to-rendered-templates
INFO  [alembic.runtime.migration] Running upgrade 45ba3f1493b9 -> 849da589634d, Prefix DAG permissions.
INFO  [alembic.runtime.migration] Running upgrade 849da589634d -> 2c6edca13270, Resource based permissions.
[2021-10-25 19:01:51,033] {manager.py:784} WARNING - No user yet created, use flask fab command to do it.
INFO  [alembic.runtime.migration] Running upgrade 2c6edca13270 -> 61ec73d9401f, Add description field to connection
INFO  [alembic.runtime.migration] Running upgrade 61ec73d9401f -> 64a7d6477aae, fix description field in connection to be text
INFO  [alembic.runtime.migration] Running upgrade 64a7d6477aae -> e959f08ac86c, Change field in DagCode to MEDIUMTEXT for MySql
INFO  [alembic.runtime.migration] Running upgrade e959f08ac86c -> 82b7c48c147f, Remove can_read permission on config resource for User and Viewer role
[2021-10-25 19:01:54,450] {manager.py:784} WARNING - No user yet created, use flask fab command to do it.
INFO  [alembic.runtime.migration] Running upgrade 82b7c48c147f -> 449b4072c2da, Increase size of connection.extra field to handle multiple RSA keys
INFO  [alembic.runtime.migration] Running upgrade 449b4072c2da -> 8646922c8a04, Change default pool_slots to 1
INFO  [alembic.runtime.migration] Running upgrade 8646922c8a04 -> 2e42bb497a22, rename last_scheduler_run column
INFO  [alembic.runtime.migration] Running upgrade 2e42bb497a22 -> 90d1635d7b86, Increase pool name size in TaskInstance
INFO  [alembic.runtime.migration] Running upgrade 90d1635d7b86 -> e165e7455d70, add description field to variable
INFO  [alembic.runtime.migration] Running upgrade e165e7455d70 -> a13f7613ad25, Resource based permissions for default FAB views.
[2021-10-25 19:01:55,657] {manager.py:784} WARNING - No user yet created, use flask fab command to do it.
Upgrades done
########################################################################################################################
                                     RUNNING "/usr/local/airflow/.local/bin/pytest"
########################################################################################################################
================================================= test session starts ==================================================
platform linux -- Python 3.9.6, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /usr/local/airflow
plugins: mock-3.6.1, socket-0.4.0, anyio-3.2.1
collected 692 items                                                                                                    

tests/dags/test_common_api_workflows.py .........                                                                [  1%]
tests/dags/test_dag_parsing.py .............................                                                     [  5%]
tests/dags/common/test_requester.py ......                                                                       [  6%]
tests/dags/common/test_urls.py ................                                                                  [  8%]
tests/dags/common/licenses/test_constants.py ....                                                                [  9%]
tests/dags/common/licenses/test_licenses.py ................                                                     [ 11%]
tests/dags/provider_api_scripts/test_brooklyn_museum.py ....................                                     [ 14%]
tests/dags/provider_api_scripts/test_cleveland_museum_of_art.py ...........                                      [ 16%]
tests/dags/provider_api_scripts/test_europeana.py ......................                                         [ 19%]
tests/dags/provider_api_scripts/test_finnish_museums.py ............                                             [ 20%]
tests/dags/provider_api_scripts/test_flickr.py ..........................................                        [ 27%]
tests/dags/provider_api_scripts/test_jamendo.py .................                                                [ 29%]
tests/dags/provider_api_scripts/test_metropolitan_museum_of_art.py .......                                       [ 30%]
tests/dags/provider_api_scripts/test_museum_victoria.py ................                                         [ 32%]
tests/dags/provider_api_scripts/test_nypl.py ................                                                    [ 35%]
tests/dags/provider_api_scripts/test_phylopic.py ..............                                                  [ 37%]
tests/dags/provider_api_scripts/test_raw_pixel.py ..........                                                     [ 38%]
tests/dags/provider_api_scripts/test_science_museum.py ............................                              [ 42%]
tests/dags/provider_api_scripts/test_smithsonian.py ............................................................ [ 51%]
........................................................                                                         [ 59%]
tests/dags/provider_api_scripts/test_staten_museum.py ..................                                         [ 61%]
tests/dags/provider_api_scripts/test_stocksnap.py ..........                                                     [ 63%]
tests/dags/provider_api_scripts/test_walters_art_museum.py ................                                      [ 65%]
tests/dags/provider_api_scripts/test_wikimedia_commons.py ..................................                     [ 70%]
tests/dags/provider_api_scripts/test_wordpress.py ...............                                                [ 72%]
tests/dags/provider_api_scripts/modules/test_etlMods.py ................                                         [ 75%]
tests/dags/storage/test_audio.py ................                                                                [ 77%]
tests/dags/storage/test_columns.py ....................................                                          [ 82%]
tests/dags/storage/test_image.py ...........                                                                     [ 84%]
tests/dags/storage/test_media.py .......................                                                         [ 87%]
tests/dags/storage/test_util.py ....                                                                             [ 88%]
tests/dags/util/test_dag_factory.py ..                                                                           [ 88%]
tests/dags/util/test_helpers.py ..                                                                               [ 88%]
tests/dags/util/test_log_cleanup.py ...                                                                          [ 89%]
tests/dags/util/test_operator_util.py ...                                                                        [ 89%]
tests/dags/util/test_tsv_cleaner.py .                                                                            [ 89%]
tests/dags/util/etl/test_operators.py ...                                                                        [ 90%]
tests/dags/util/loader/test_ingestion_column.py ...                                                              [ 90%]
tests/dags/util/loader/test_paths.py ................                                                            [ 92%]
tests/dags/util/loader/test_s3.py ......                                                                         [ 93%]
tests/dags/util/loader/test_smithsonian_unit_codes.py ..                                                         [ 94%]
tests/dags/util/loader/test_sql.py ..................................                                            [ 98%]
tests/dags/util/popularity/test_sql.py ......                                                                    [ 99%]
tests/templates/test_create_api_script.py .                                                                      [100%]

================================================= 692 passed in 27.68s =================================================
Sample output on initialized instance
$ dc run --rm webserver airflow dags list
Creating openverse-catalog_webserver_run ... done
########################################################################################################################
                                                  WAITING FOR POSTGRES
########################################################################################################################
2021-10-25 19:05:27,075 - /usr/local/airflow/wait_for_db.py - INFO:  Testing DB connection postgresql+psycopg2://airflow:airflow@postgres:5432/airflow
########################################################################################################################
                                                   MIGRATING DATABASE
########################################################################################################################
DB: postgresql+psycopg2://airflow:***@postgres:5432/airflow
[2021-10-25 19:05:28,134] {db.py:692} INFO - Creating tables
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
Upgrades done
########################################################################################################################
                                              RUNNING "airflow dags list"
########################################################################################################################
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 9, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 15, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(1970, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 9, 27, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
{'owner': 'data-eng-admin', 'depends_on_past': False, 'start_date': datetime.datetime(2020, 1, 1, 0, 0), 'email_on_retry': False, 'retries': 3, 'retry_delay': datetime.timedelta(seconds=900)}
dag_id                                    | filepath                                     | owner          | paused
==========================================+==============================================+================+=======
airflow_log_cleanup                       | airflow_log_cleanup_workflow.py              | data-eng-admin | True  
brooklyn_museum_workflow                  | brooklyn_museum_workflow.py                  | data-eng-admin | True  
check_new_smithsonian_unit_codes_workflow | check_new_smithsonian_unit_codes_workflow.py | data-eng-admin | True  
cleveland_museum_workflow                 | cleveland_museum_workflow.py                 | data-eng-admin | True  
europeana_ingestion_workflow              | europeana_ingestion_workflow.py              | data-eng-admin | True  
europeana_sub_provider_update_workflow    | europeana_sub_provider_update_workflow.py    | data-eng-admin | True  
europeana_workflow                        | europeana_workflow.py                        | data-eng-admin | True  
finnish_museums_workflow                  | finnish_museums_workflow.py                  | data-eng-admin | True  
flickr_ingestion_workflow                 | flickr_ingestion_workflow.py                 | data-eng-admin | True  
flickr_sub_provider_update_workflow       | flickr_sub_provider_update_workflow.py       | data-eng-admin | True  
flickr_workflow                           | flickr_workflow.py                           | data-eng-admin | True  
healthcheck_workflow                      | healthcheck_workflow.py                      | data-eng-admin | True  
image_expiration_workflow                 | image_expiration_workflow.py                 | data-eng-admin | True  
jamendo_workflow                          | jamendo_workflow.py                          | data-eng-admin | True  
metropolitan_museum_workflow              | metropolitan_museum_workflow.py              | data-eng-admin | True  
museum_victoria_workflow                  | museum_victoria_workflow.py                  | data-eng-admin | True  
nypl_workflow                             | nypl_workflow.py                             | data-eng-admin | True  
phylopic_workflow                         | phylopic_workflow.py                         | data-eng-admin | True  
postgres_image_cleaner                    | cleaner_workflow.py                          | data-eng-admin | True  
rawpixel_workflow                         | rawpixel_workflow.py                         | data-eng-admin | True  
recreate_audio_popularity_calculation     | recreate_audio_popularity_calculation.py     | data-eng-admin | True  
recreate_image_popularity_calculation     | recreate_image_popularity_calculation.py     | data-eng-admin | True  
refresh_all_audio_popularity_data         | refresh_all_audio_popularity_data.py         | data-eng-admin | True  
refresh_all_image_popularity_data         | refresh_all_image_popularity_data.py         | data-eng-admin | True  
refresh_audio_view_data                   | refresh_audio_view_data.py                   | data-eng-admin | True  
refresh_image_view_data                   | refresh_image_view_data.py                   | data-eng-admin | True  
science_museum_workflow                   | science_museum_workflow.py                   | data-eng-admin | True  
smithsonian_sub_provider_update_workflow  | smithsonian_sub_provider_update_workflow.py  | data-eng-admin | True  
smithsonian_workflow                      | smithsonian_workflow.py                      | data-eng-admin | True  
staten_museum_workflow                    | statens_museum_workflow.py                   | data-eng-admin | True  
stocksnap_workflow                        | stocksnap_workflow.py                        | data-eng-admin | True  
tsv_to_postgres_loader                    | loader_workflow.py                           | data-eng-admin | True  
tsv_to_postgres_loader_overwrite          | loader_workflow.py                           | data-eng-admin | True  
walters_workflow                          | walters_workflow.py                          | data-eng-admin | True  
wikimedia_commons_workflow                | wikimedia_workflow.py                        | data-eng-admin | True  
wikimedia_ingestion_workflow              | wikimedia_ingestion_workflow.py              | data-eng-admin | True  
wordpress_workflow                        | wordpress_workflow.py                        | data-eng-admin | True  

Testing Instructions

  1. just down -v
  2. just build
  3. just test
  4. Observe that only postgres and s3 services are started and that the DB is migrated successfully beforehand.
  5. (Optionally) dc run --rm webserver help

Checklist

  • My pull request has a descriptive title (not a vague title like Update index.md).
  • My pull request targets the default branch of the repository (main) or a parent feature branch.
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • I added or updated tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no visible errors.

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

@AetherUnbound AetherUnbound requested a review from a team as a code owner October 25, 2021 19:19
@AetherUnbound AetherUnbound added ✨ goal: improvement Improvement to an existing user-facing feature 🤖 aspect: dx Concerns developers' experience with the codebase labels Oct 25, 2021
@dhruvkb dhruvkb added this to Needs review in Openverse PRs Oct 25, 2021
Copy link
Member

@zackkrida zackkrida left a comment

Choose a reason for hiding this comment

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

This all looks great but I have some test failures locally that I'm curious about.

Test Failures
============================= test session starts ==============================
platform linux -- Python 3.9.7, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /usr/local/airflow
plugins: mock-3.6.1, socket-0.4.0, anyio-3.2.1
collected 692 items

tests/dags/test_common_api_workflows.py .........                        [  1%]
tests/dags/test_dag_parsing.py .............................             [  5%]
tests/dags/common/test_requester.py ......                               [  6%]
tests/dags/common/test_urls.py ................                          [  8%]
tests/dags/common/licenses/test_constants.py ....                        [  9%]
tests/dags/common/licenses/test_licenses.py ................             [ 11%]
tests/dags/provider_api_scripts/test_brooklyn_museum.py ................ [ 13%]
....                                                                     [ 14%]
tests/dags/provider_api_scripts/test_cleveland_museum_of_art.py ........ [ 15%]
...                                                                      [ 16%]
tests/dags/provider_api_scripts/test_europeana.py ...................... [ 19%]
                                                                         [ 19%]
tests/dags/provider_api_scripts/test_finnish_museums.py ............     [ 20%]
tests/dags/provider_api_scripts/test_flickr.py ......................... [ 24%]
.................                                                        [ 27%]
tests/dags/provider_api_scripts/test_jamendo.py .................        [ 29%]
tests/dags/provider_api_scripts/test_metropolitan_museum_of_art.py ..... [ 30%]
..                                                                       [ 30%]
tests/dags/provider_api_scripts/test_museum_victoria.py ................ [ 32%]
                                                                         [ 32%]
tests/dags/provider_api_scripts/test_nypl.py ................            [ 35%]
tests/dags/provider_api_scripts/test_phylopic.py ..............          [ 37%]
tests/dags/provider_api_scripts/test_raw_pixel.py ..........             [ 38%]
tests/dags/provider_api_scripts/test_science_museum.py ................. [ 41%]
...........                                                              [ 42%]
tests/dags/provider_api_scripts/test_smithsonian.py .................... [ 45%]
........................................................................ [ 55%]
........................                                                 [ 59%]
tests/dags/provider_api_scripts/test_staten_museum.py .................. [ 61%]
                                                                         [ 61%]
tests/dags/provider_api_scripts/test_stocksnap.py ..........             [ 63%]
tests/dags/provider_api_scripts/test_walters_art_museum.py ............. [ 65%]
...                                                                      [ 65%]
tests/dags/provider_api_scripts/test_wikimedia_commons.py .............. [ 67%]
....................                                                     [ 70%]
tests/dags/provider_api_scripts/test_wordpress.py ...............        [ 72%]
tests/dags/provider_api_scripts/modules/test_etlMods.py ................ [ 75%]
                                                                         [ 75%]
tests/dags/storage/test_audio.py ................                        [ 77%]
tests/dags/storage/test_columns.py ....................................  [ 82%]
tests/dags/storage/test_image.py ...........                             [ 84%]
tests/dags/storage/test_media.py .......................                 [ 87%]
tests/dags/storage/test_util.py ....                                     [ 88%]
tests/dags/util/test_dag_factory.py ..                                   [ 88%]
tests/dags/util/test_helpers.py ..                                       [ 88%]
tests/dags/util/test_log_cleanup.py ...                                  [ 89%]
tests/dags/util/test_operator_util.py .FF                                [ 89%]
tests/dags/util/test_tsv_cleaner.py .                                    [ 89%]
tests/dags/util/etl/test_operators.py ...                                [ 90%]
tests/dags/util/loader/test_ingestion_column.py ...                      [ 90%]
tests/dags/util/loader/test_paths.py FFFFF...........                    [ 92%]
tests/dags/util/loader/test_s3.py ......                                 [ 93%]
tests/dags/util/loader/test_smithsonian_unit_codes.py ..                 [ 94%]
tests/dags/util/loader/test_sql.py FF...........................F....    [ 98%]
tests/dags/util/popularity/test_sql.py ......                            [ 99%]
tests/templates/test_create_api_script.py .                              [100%]

=================================== FAILURES ===================================
________________ test_get_dated_main_runner_handles_zero_shift _________________

self = <sqlalchemy.engine.base.Connection object at 0xffff8d73aa30>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'SELECT task_instance.try_number AS task_instance_try_number, task_instance.task_id AS task_instance_task_id, task_ins...stance.task_id = %(task_id_1)s AND task_instance.execution_date = %(execution_date_1)s \n LIMIT %(param_1)s FOR UPDATE'
parameters = {'dag_id_1': 'test_dag', 'execution_date_1': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1, 'task_id_1': 'pull_image_data'}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8d73a430>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8d73a370>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d4405b0>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8d5ed310; closed: -1>
statement = 'SELECT task_instance.try_number AS task_instance_try_number, task_instance.task_id AS task_instance_task_id, task_ins...stance.task_id = %(task_id_1)s AND task_instance.execution_date = %(execution_date_1)s \n LIMIT %(param_1)s FOR UPDATE'
parameters = {'dag_id_1': 'test_dag', 'execution_date_1': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1, 'task_id_1': 'pull_image_data'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d4405b0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "task_instance" does not exist
E       LINE 2: FROM task_instance 
E                    ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

capsys = <_pytest.capture.CaptureFixture object at 0xffff8d73afd0>

    def test_get_dated_main_runner_handles_zero_shift(capsys):
        dag = DAG(dag_id="test_dag", start_date=datetime.strptime("2019-01-01", "%Y-%m-%d"))
        execution_date = datetime.strptime("2019-01-01", "%Y-%m-%d").replace(
            tzinfo=timezone.utc
        )
        main_func = dated
        with dag:
            runner = op_util.get_dated_main_runner_operator(main_func, timedelta(minutes=1))
            ti = TaskInstance(runner, execution_date)
>           ti.run(ignore_task_deps=True, ignore_ti_state=True, test_mode=True)

tests/dags/util/test_operator_util.py:27: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1415: in run
    res = self.check_and_change_state_before_execution(
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1023: in check_and_change_state_before_execution
    self.refresh_from_db(session=session, lock_for_update=True)
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:623: in refresh_from_db
    ti = qry.with_for_update().first()
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3429: in first
    ret = list(self[0:1])
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3203: in __getitem__
    return list(res)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3535: in __iter__
    return self._execute_and_instances(context)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3560: in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8d5ed310; closed: -1>
statement = 'SELECT task_instance.try_number AS task_instance_try_number, task_instance.task_id AS task_instance_task_id, task_ins...stance.task_id = %(task_id_1)s AND task_instance.execution_date = %(execution_date_1)s \n LIMIT %(param_1)s FOR UPDATE'
parameters = {'dag_id_1': 'test_dag', 'execution_date_1': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1, 'task_id_1': 'pull_image_data'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d4405b0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "task_instance" does not exist
E       LINE 2: FROM task_instance 
E                    ^
E       
E       [SQL: SELECT task_instance.try_number AS task_instance_try_number, task_instance.task_id AS task_instance_task_id, task_instance.dag_id AS task_instance_dag_id, task_instance.execution_date AS task_instance_execution_date, task_instance.start_date AS task_instance_start_date, task_instance.end_date AS task_instance_end_date, task_instance.duration AS task_instance_duration, task_instance.state AS task_instance_state, task_instance.max_tries AS task_instance_max_tries, task_instance.hostname AS task_instance_hostname, task_instance.unixname AS task_instance_unixname, task_instance.job_id AS task_instance_job_id, task_instance.pool AS task_instance_pool, task_instance.pool_slots AS task_instance_pool_slots, task_instance.queue AS task_instance_queue, task_instance.priority_weight AS task_instance_priority_weight, task_instance.operator AS task_instance_operator, task_instance.queued_dttm AS task_instance_queued_dttm, task_instance.queued_by_job_id AS task_instance_queued_by_job_id, task_instance.pid AS task_instance_pid, task_instance.executor_config AS task_instance_executor_config, task_instance.external_executor_id AS task_instance_external_executor_id 
E       FROM task_instance 
E       WHERE task_instance.dag_id = %(dag_id_1)s AND task_instance.task_id = %(task_id_1)s AND task_instance.execution_date = %(execution_date_1)s 
E        LIMIT %(param_1)s FOR UPDATE]
E       [parameters: {'dag_id_1': 'test_dag', 'task_id_1': 'pull_image_data', 'execution_date_1': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
_________________ test_get_dated_main_runner_handles_day_shift _________________

self = <sqlalchemy.engine.base.Connection object at 0xffff8d419790>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'SELECT task_instance.try_number AS task_instance_try_number, task_instance.task_id AS task_instance_task_id, task_ins...stance.task_id = %(task_id_1)s AND task_instance.execution_date = %(execution_date_1)s \n LIMIT %(param_1)s FOR UPDATE'
parameters = {'dag_id_1': 'test_dag', 'execution_date_1': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1, 'task_id_1': 'pull_image_data'}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8d419730>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8d4197f0>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d419850>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8d5ed9a0; closed: -1>
statement = 'SELECT task_instance.try_number AS task_instance_try_number, task_instance.task_id AS task_instance_task_id, task_ins...stance.task_id = %(task_id_1)s AND task_instance.execution_date = %(execution_date_1)s \n LIMIT %(param_1)s FOR UPDATE'
parameters = {'dag_id_1': 'test_dag', 'execution_date_1': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1, 'task_id_1': 'pull_image_data'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d419850>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "task_instance" does not exist
E       LINE 2: FROM task_instance 
E                    ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

capsys = <_pytest.capture.CaptureFixture object at 0xffff8cfc0a90>

    def test_get_dated_main_runner_handles_day_shift(capsys):
        dag = DAG(dag_id="test_dag", start_date=datetime.strptime("2019-01-01", "%Y-%m-%d"))
        execution_date = datetime.strptime("2019-01-01", "%Y-%m-%d").replace(
            tzinfo=timezone.utc
        )
        main_func = dated
        with dag:
            runner = op_util.get_dated_main_runner_operator(
                main_func, timedelta(minutes=1), day_shift=1
            )
            ti = TaskInstance(runner, execution_date)
>           ti.run(ignore_task_deps=True, ignore_ti_state=True, test_mode=True)

tests/dags/util/test_operator_util.py:46: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1415: in run
    res = self.check_and_change_state_before_execution(
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1023: in check_and_change_state_before_execution
    self.refresh_from_db(session=session, lock_for_update=True)
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:623: in refresh_from_db
    ti = qry.with_for_update().first()
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3429: in first
    ret = list(self[0:1])
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3203: in __getitem__
    return list(res)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3535: in __iter__
    return self._execute_and_instances(context)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3560: in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8d5ed9a0; closed: -1>
statement = 'SELECT task_instance.try_number AS task_instance_try_number, task_instance.task_id AS task_instance_task_id, task_ins...stance.task_id = %(task_id_1)s AND task_instance.execution_date = %(execution_date_1)s \n LIMIT %(param_1)s FOR UPDATE'
parameters = {'dag_id_1': 'test_dag', 'execution_date_1': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1, 'task_id_1': 'pull_image_data'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d419850>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "task_instance" does not exist
E       LINE 2: FROM task_instance 
E                    ^
E       
E       [SQL: SELECT task_instance.try_number AS task_instance_try_number, task_instance.task_id AS task_instance_task_id, task_instance.dag_id AS task_instance_dag_id, task_instance.execution_date AS task_instance_execution_date, task_instance.start_date AS task_instance_start_date, task_instance.end_date AS task_instance_end_date, task_instance.duration AS task_instance_duration, task_instance.state AS task_instance_state, task_instance.max_tries AS task_instance_max_tries, task_instance.hostname AS task_instance_hostname, task_instance.unixname AS task_instance_unixname, task_instance.job_id AS task_instance_job_id, task_instance.pool AS task_instance_pool, task_instance.pool_slots AS task_instance_pool_slots, task_instance.queue AS task_instance_queue, task_instance.priority_weight AS task_instance_priority_weight, task_instance.operator AS task_instance_operator, task_instance.queued_dttm AS task_instance_queued_dttm, task_instance.queued_by_job_id AS task_instance_queued_by_job_id, task_instance.pid AS task_instance_pid, task_instance.executor_config AS task_instance_executor_config, task_instance.external_executor_id AS task_instance_external_executor_id 
E       FROM task_instance 
E       WHERE task_instance.dag_id = %(dag_id_1)s AND task_instance.task_id = %(task_id_1)s AND task_instance.execution_date = %(execution_date_1)s 
E        LIMIT %(param_1)s FOR UPDATE]
E       [parameters: {'dag_id_1': 'test_dag', 'task_id_1': 'pull_image_data', 'execution_date_1': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
__________________ test_stage_oldest_tsv_file_finds_tsv_file ___________________

self = <sqlalchemy.engine.base.Connection object at 0xffff8d442b50>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8d442b80>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8d442b20>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d442be0>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8db62b80; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d442be0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

tmpdir = local('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0')

    def test_stage_oldest_tsv_file_finds_tsv_file(tmpdir):
        tmp_directory = str(tmpdir)
        identifier = TEST_ID
        test_tsv = "test_v002_.tsv"
        path = tmpdir.join(test_tsv)
        path.write("")
>       tsv_found = paths.stage_oldest_tsv_file(
            tmp_directory,
            identifier,
            0,
            ti,
        )

tests/dags/util/loader/test_paths.py:24: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
openverse_catalog/dags/util/loader/paths.py:52: in stage_oldest_tsv_file
    ti.xcom_push(key="media_type", value=media_type)
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1937: in xcom_push
    XCom.set(
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/xcom.py:82: in set
    session.query(cls).filter(
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3926: in delete
    delete_op.exec_()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1697: in exec_
    self._do_exec()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1930: in _do_exec
    self._execute_stmt(delete_stmt)
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1702: in _execute_stmt
    self.result = self.query._execute_crud(stmt, self.mapper)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3568: in _execute_crud
    return conn.execute(stmt, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8db62b80; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d442be0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^
E       
E       [SQL: DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s]
E       [parameters: {'key_1': 'media_type', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'task_id_1': 'op_no_dag', 'dag_id_1': 'adhoc_airflow'}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
----------------------------- Captured stdout call -----------------------------
[�[34m2021-10-25 21:38:39,562�[0m] {�[34mpaths.py:�[0m109} INFO�[0m - getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0�[0m
[�[34m2021-10-25 21:38:39,562�[0m] {�[34mpaths.py:�[0m111} INFO�[0m - found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0/test_v002_.tsv']�[0m
[�[34m2021-10-25 21:38:39,562�[0m] {�[34mpaths.py:�[0m113} INFO�[0m - last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0/test_v002_.tsv', 1635197919.561753)]�[0m
[�[34m2021-10-25 21:38:39,563�[0m] {�[34mpaths.py:�[0m132} INFO�[0m - Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0/test_v002_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0/db_loader_staging/testing/test_v002_.tsv�[0m
------------------------------ Captured log call -------------------------------
INFO     util.loader.paths:paths.py:109 getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0
INFO     util.loader.paths:paths.py:111 found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0/test_v002_.tsv']
INFO     util.loader.paths:paths.py:113 last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0/test_v002_.tsv', 1635197919.561753)]
INFO     util.loader.paths:paths.py:132 Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0/test_v002_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_fin0/db_loader_staging/testing/test_v002_.tsv
__________________ test_stage_oldest_tsv_file_stages_tsv_file __________________

self = <sqlalchemy.engine.base.Connection object at 0xffff8ce9ac10>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8ce9aca0>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8ce9ad60>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8ce9ab20>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8db62c70; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8ce9ab20>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

tmpdir = local('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0')

    def test_stage_oldest_tsv_file_stages_tsv_file(tmpdir):
        tmp_directory = str(tmpdir)
        staging_subdirectory = paths.STAGING_SUBDIRECTORY
        identifier = TEST_ID
        test_tsv = "test_v002_.tsv"
        path = tmpdir.join(test_tsv)
        path.write("")
>       paths.stage_oldest_tsv_file(tmp_directory, identifier, 0, ti)

tests/dags/util/loader/test_paths.py:41: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
openverse_catalog/dags/util/loader/paths.py:52: in stage_oldest_tsv_file
    ti.xcom_push(key="media_type", value=media_type)
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1937: in xcom_push
    XCom.set(
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/xcom.py:82: in set
    session.query(cls).filter(
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3926: in delete
    delete_op.exec_()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1697: in exec_
    self._do_exec()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1930: in _do_exec
    self._execute_stmt(delete_stmt)
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1702: in _execute_stmt
    self.result = self.query._execute_crud(stmt, self.mapper)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3568: in _execute_crud
    return conn.execute(stmt, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8db62c70; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8ce9ab20>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^
E       
E       [SQL: DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s]
E       [parameters: {'key_1': 'media_type', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'task_id_1': 'op_no_dag', 'dag_id_1': 'adhoc_airflow'}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
----------------------------- Captured stdout call -----------------------------
[�[34m2021-10-25 21:38:39,734�[0m] {�[34mpaths.py:�[0m109} INFO�[0m - getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0�[0m
[�[34m2021-10-25 21:38:39,734�[0m] {�[34mpaths.py:�[0m111} INFO�[0m - found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0/test_v002_.tsv']�[0m
[�[34m2021-10-25 21:38:39,734�[0m] {�[34mpaths.py:�[0m113} INFO�[0m - last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0/test_v002_.tsv', 1635197919.732753)]�[0m
[�[34m2021-10-25 21:38:39,734�[0m] {�[34mpaths.py:�[0m132} INFO�[0m - Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0/test_v002_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0/db_loader_staging/testing/test_v002_.tsv�[0m
------------------------------ Captured log call -------------------------------
INFO     util.loader.paths:paths.py:109 getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0
INFO     util.loader.paths:paths.py:111 found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0/test_v002_.tsv']
INFO     util.loader.paths:paths.py:113 last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0/test_v002_.tsv', 1635197919.732753)]
INFO     util.loader.paths:paths.py:132 Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0/test_v002_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta0/db_loader_staging/testing/test_v002_.tsv
________ test_stage_oldest_tsv_file_removes_staged_file_from_output_dir ________

self = <sqlalchemy.engine.base.Connection object at 0xffff8d61ea90>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8d61e9d0>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8d61e670>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d61e3d0>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8db62b80; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d61e3d0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

tmpdir = local('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0')

    def test_stage_oldest_tsv_file_removes_staged_file_from_output_dir(tmpdir):
        tmp_directory = str(tmpdir)
        identifier = TEST_ID
        test_tsv = "test_v002_.tsv"
        path = tmpdir.join(test_tsv)
        path.write("")
>       paths.stage_oldest_tsv_file(tmp_directory, identifier, 0, ti)

tests/dags/util/loader/test_paths.py:53: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
openverse_catalog/dags/util/loader/paths.py:52: in stage_oldest_tsv_file
    ti.xcom_push(key="media_type", value=media_type)
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1937: in xcom_push
    XCom.set(
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/xcom.py:82: in set
    session.query(cls).filter(
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3926: in delete
    delete_op.exec_()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1697: in exec_
    self._do_exec()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1930: in _do_exec
    self._execute_stmt(delete_stmt)
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1702: in _execute_stmt
    self.result = self.query._execute_crud(stmt, self.mapper)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3568: in _execute_crud
    return conn.execute(stmt, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8db62b80; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d61e3d0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^
E       
E       [SQL: DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s]
E       [parameters: {'key_1': 'media_type', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'task_id_1': 'op_no_dag', 'dag_id_1': 'adhoc_airflow'}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
----------------------------- Captured stdout call -----------------------------
[�[34m2021-10-25 21:38:39,888�[0m] {�[34mpaths.py:�[0m109} INFO�[0m - getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0�[0m
[�[34m2021-10-25 21:38:39,888�[0m] {�[34mpaths.py:�[0m111} INFO�[0m - found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0/test_v002_.tsv']�[0m
[�[34m2021-10-25 21:38:39,888�[0m] {�[34mpaths.py:�[0m113} INFO�[0m - last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0/test_v002_.tsv', 1635197919.887753)]�[0m
[�[34m2021-10-25 21:38:39,888�[0m] {�[34mpaths.py:�[0m132} INFO�[0m - Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0/test_v002_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0/db_loader_staging/testing/test_v002_.tsv�[0m
------------------------------ Captured log call -------------------------------
INFO     util.loader.paths:paths.py:109 getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0
INFO     util.loader.paths:paths.py:111 found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0/test_v002_.tsv']
INFO     util.loader.paths:paths.py:113 last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0/test_v002_.tsv', 1635197919.887753)]
INFO     util.loader.paths:paths.py:132 Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0/test_v002_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_rem0/db_loader_staging/testing/test_v002_.tsv
_________________ test_stage_oldest_tsv_file_stages_older_file _________________

self = <sqlalchemy.engine.base.Connection object at 0xffff8cacc040>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8cacc0d0>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8cacc190>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cacc940>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8db62e50; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cacc940>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

tmpdir = local('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1')

    def test_stage_oldest_tsv_file_stages_older_file(tmpdir):
        tmp_directory = str(tmpdir)
        staging_subdirectory = paths.STAGING_SUBDIRECTORY
        identifier = TEST_ID
        test_one_tsv = "test1_v001_.tsv"
        test_two_tsv = "test2_v001_.tsv"
        path_one = tmpdir.join(test_one_tsv)
        path_one.write("")
        time.sleep(0.01)
        path_two = tmpdir.join(test_two_tsv)
        path_two.write("")
>       paths.stage_oldest_tsv_file(tmp_directory, identifier, 0, ti)

tests/dags/util/loader/test_paths.py:69: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
openverse_catalog/dags/util/loader/paths.py:52: in stage_oldest_tsv_file
    ti.xcom_push(key="media_type", value=media_type)
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1937: in xcom_push
    XCom.set(
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/xcom.py:82: in set
    session.query(cls).filter(
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3926: in delete
    delete_op.exec_()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1697: in exec_
    self._do_exec()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1930: in _do_exec
    self._execute_stmt(delete_stmt)
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1702: in _execute_stmt
    self.result = self.query._execute_crud(stmt, self.mapper)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3568: in _execute_crud
    return conn.execute(stmt, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8db62e50; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cacc940>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^
E       
E       [SQL: DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s]
E       [parameters: {'key_1': 'media_type', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'task_id_1': 'op_no_dag', 'dag_id_1': 'adhoc_airflow'}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
----------------------------- Captured stdout call -----------------------------
[�[34m2021-10-25 21:38:40,054�[0m] {�[34mpaths.py:�[0m109} INFO�[0m - getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1�[0m
[�[34m2021-10-25 21:38:40,054�[0m] {�[34mpaths.py:�[0m111} INFO�[0m - found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test2_v001_.tsv', '/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test1_v001_.tsv']�[0m
[�[34m2021-10-25 21:38:40,054�[0m] {�[34mpaths.py:�[0m113} INFO�[0m - last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test2_v001_.tsv', 1635197920.053753), ('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test1_v001_.tsv', 1635197920.041753)]�[0m
[�[34m2021-10-25 21:38:40,054�[0m] {�[34mpaths.py:�[0m132} INFO�[0m - Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test1_v001_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/db_loader_staging/testing/test1_v001_.tsv�[0m
------------------------------ Captured log call -------------------------------
INFO     util.loader.paths:paths.py:109 getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1
INFO     util.loader.paths:paths.py:111 found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test2_v001_.tsv', '/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test1_v001_.tsv']
INFO     util.loader.paths:paths.py:113 last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test2_v001_.tsv', 1635197920.053753), ('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test1_v001_.tsv', 1635197920.041753)]
INFO     util.loader.paths:paths.py:132 Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/test1_v001_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_sta1/db_loader_staging/testing/test1_v001_.tsv
________________ test_stage_oldest_tsv_file_ignores_newer_file _________________

self = <sqlalchemy.engine.base.Connection object at 0xffff8cd445e0>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8cd446a0>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8cd44670>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cd445b0>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8d55aa90; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cd445b0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

tmpdir = local('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0')

    def test_stage_oldest_tsv_file_ignores_newer_file(tmpdir):
        tmp_directory = str(tmpdir)
        staging_subdirectory = paths.STAGING_SUBDIRECTORY
        identifier = TEST_ID
        test_one_tsv = "test1_v002_.tsv"
        test_two_tsv = "test2_v002_.tsv"
        path_one = tmpdir.join(test_one_tsv)
        path_one.write("")
        time.sleep(0.01)
        path_two = tmpdir.join(test_two_tsv)
        path_two.write("")
>       paths.stage_oldest_tsv_file(tmp_directory, identifier, 0, ti)

tests/dags/util/loader/test_paths.py:85: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
openverse_catalog/dags/util/loader/paths.py:52: in stage_oldest_tsv_file
    ti.xcom_push(key="media_type", value=media_type)
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:1937: in xcom_push
    XCom.set(
.local/lib/python3.9/site-packages/airflow/utils/session.py:67: in wrapper
    return func(*args, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/xcom.py:82: in set
    session.query(cls).filter(
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3926: in delete
    delete_op.exec_()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1697: in exec_
    self._do_exec()
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1930: in _do_exec
    self._execute_stmt(delete_stmt)
.local/lib/python3.9/site-packages/sqlalchemy/orm/persistence.py:1702: in _execute_stmt
    self.result = self.query._execute_crud(stmt, self.mapper)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3568: in _execute_crud
    return conn.execute(stmt, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8d55aa90; closed: -1>
statement = 'DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'task_id_1': 'op_no_dag'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cd445b0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "xcom" does not exist
E       LINE 1: DELETE FROM xcom WHERE xcom.key = 'media_type' AND xcom.exec...
E                           ^
E       
E       [SQL: DELETE FROM xcom WHERE xcom.key = %(key_1)s AND xcom.execution_date = %(execution_date_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s]
E       [parameters: {'key_1': 'media_type', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'task_id_1': 'op_no_dag', 'dag_id_1': 'adhoc_airflow'}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
----------------------------- Captured stdout call -----------------------------
[�[34m2021-10-25 21:38:40,217�[0m] {�[34mpaths.py:�[0m109} INFO�[0m - getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0�[0m
[�[34m2021-10-25 21:38:40,217�[0m] {�[34mpaths.py:�[0m111} INFO�[0m - found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test1_v002_.tsv', '/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test2_v002_.tsv']�[0m
[�[34m2021-10-25 21:38:40,217�[0m] {�[34mpaths.py:�[0m113} INFO�[0m - last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test1_v002_.tsv', 1635197920.206753), ('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test2_v002_.tsv', 1635197920.216753)]�[0m
[�[34m2021-10-25 21:38:40,218�[0m] {�[34mpaths.py:�[0m132} INFO�[0m - Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test1_v002_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/db_loader_staging/testing/test1_v002_.tsv�[0m
------------------------------ Captured log call -------------------------------
INFO     util.loader.paths:paths.py:109 getting files from /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0
INFO     util.loader.paths:paths.py:111 found files:
['/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test1_v002_.tsv', '/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test2_v002_.tsv']
INFO     util.loader.paths:paths.py:113 last_modified_list:
[('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test1_v002_.tsv', 1635197920.206753), ('/tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test2_v002_.tsv', 1635197920.216753)]
INFO     util.loader.paths:paths.py:132 Moving /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/test1_v002_.tsv to /tmp/pytest-of-airflow/pytest-0/test_stage_oldest_tsv_file_ign0/db_loader_staging/testing/test1_v002_.tsv
___________________ test_create_loading_table_creates_table ____________________

self = <sqlalchemy.engine.base.Connection object at 0xffff8ce820d0>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8ce82700>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8ce82dc0>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8ce82a90>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8c63f040; closed: -1>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8ce82a90>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "xcom" does not exist
E       LINE 2: FROM xcom 
E                    ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

postgres = Postgres(cursor=<cursor object at 0xffff8c6f4e50; closed: 0>, connection=<connection object at 0xffff8c6dc180; dsn: 'user=deploy password=xxx dbname=openledger host=postgres port=5432', closed: 0>)

    def test_create_loading_table_creates_table(postgres):
        postgres_conn_id = POSTGRES_CONN_ID
        identifier = TEST_ID
        load_table = TEST_LOAD_TABLE
>       sql.create_loading_table(postgres_conn_id, identifier, ti)

tests/dags/util/loader/test_sql.py:226: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
openverse_catalog/dags/util/loader/sql.py:69: in create_loading_table
    media_type = ti.xcom_pull(task_ids="stage_oldest_tsv_file", key="media_type")
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:2010: in xcom_pull
    xcom = query.with_entities(XCom.value).first()
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3429: in first
    ret = list(self[0:1])
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3203: in __getitem__
    return list(res)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3535: in __iter__
    return self._execute_and_instances(context)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3560: in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8c63f040; closed: -1>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8ce82a90>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "xcom" does not exist
E       LINE 2: FROM xcom 
E                    ^
E       
E       [SQL: SELECT xcom.value AS xcom_value 
E       FROM xcom 
E       WHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s AND xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC 
E        LIMIT %(param_1)s]
E       [parameters: {'key_1': 'media_type', 'task_id_1': 'stage_oldest_tsv_file', 'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
__________ test_create_loading_table_errors_if_run_twice_with_same_id __________

self = <sqlalchemy.engine.base.Connection object at 0xffff8cbc2b80>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8cbc2a30>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8cbc2d30>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cbc29d0>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8c63fc70; closed: -1>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cbc29d0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "xcom" does not exist
E       LINE 2: FROM xcom 
E                    ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

postgres = Postgres(cursor=<cursor object at 0xffff8c63fa90; closed: 0>, connection=<connection object at 0xffff8c6dca40; dsn: 'user=deploy password=xxx dbname=openledger host=postgres port=5432', closed: 0>)

    def test_create_loading_table_errors_if_run_twice_with_same_id(postgres):
        postgres_conn_id = POSTGRES_CONN_ID
        identifier = TEST_ID
>       sql.create_loading_table(postgres_conn_id, identifier, ti)

tests/dags/util/loader/test_sql.py:239: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
openverse_catalog/dags/util/loader/sql.py:69: in create_loading_table
    media_type = ti.xcom_pull(task_ids="stage_oldest_tsv_file", key="media_type")
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:2010: in xcom_pull
    xcom = query.with_entities(XCom.value).first()
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3429: in first
    ret = list(self[0:1])
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3203: in __getitem__
    return list(res)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3535: in __iter__
    return self._execute_and_instances(context)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3560: in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8c63fc70; closed: -1>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8cbc29d0>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "xcom" does not exist
E       LINE 2: FROM xcom 
E                    ^
E       
E       [SQL: SELECT xcom.value AS xcom_value 
E       FROM xcom 
E       WHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s AND xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC 
E        LIMIT %(param_1)s]
E       [parameters: {'key_1': 'media_type', 'task_id_1': 'stage_oldest_tsv_file', 'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
_______________________ test_drop_load_table_drops_table _______________________

self = <sqlalchemy.engine.base.Connection object at 0xffff8d457160>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0xffff8d4571f0>, [immutabledict({})])
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0xffff8d457310>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d457640>

    def _execute_context(
        self, dialect, constructor, statement, parameters, *args
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.ResultProxy`.
    
        """
    
        try:
            try:
                conn = self.__connection
            except AttributeError:
                # escape "except AttributeError" before revalidating
                # to prevent misleading stacktraces in Py3K
                conn = None
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(dialect, self, conn, *args)
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if context.compiled:
            context.pre_exec()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
            self.engine.logger.info(statement)
            if not self.engine.hide_parameters:
                self.engine.logger.info(
                    "%r",
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self.engine.logger.info(
                    "[SQL parameters hidden due to hide_parameters=True]"
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8d49ee50; closed: -1>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d457640>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.UndefinedTable: relation "xcom" does not exist
E       LINE 2: FROM xcom 
E                    ^

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: UndefinedTable

The above exception was the direct cause of the following exception:

postgres_with_load_table = Postgres(cursor=<cursor object at 0xffff8d55aa90; closed: 0>, connection=<connection object at 0xffff8c6dc180; dsn: 'user=deploy password=xxx dbname=openledger host=postgres port=5432', closed: 0>)

    def test_drop_load_table_drops_table(postgres_with_load_table):
        postgres_conn_id = POSTGRES_CONN_ID
        identifier = TEST_ID
        load_table = TEST_LOAD_TABLE
>       sql.drop_load_table(postgres_conn_id, identifier, ti)

tests/dags/util/loader/test_sql.py:1252: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
openverse_catalog/dags/util/loader/sql.py:302: in drop_load_table
    media_type = ti.xcom_pull(task_ids="stage_oldest_tsv_file", key="media_type")
.local/lib/python3.9/site-packages/airflow/utils/session.py:70: in wrapper
    return func(*args, session=session, **kwargs)
.local/lib/python3.9/site-packages/airflow/models/taskinstance.py:2010: in xcom_pull
    xcom = query.with_entities(XCom.value).first()
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3429: in first
    ret = list(self[0:1])
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3203: in __getitem__
    return list(res)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3535: in __iter__
    return self._execute_and_instances(context)
.local/lib/python3.9/site-packages/sqlalchemy/orm/query.py:3560: in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1011: in execute
    return meth(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py:298: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1124: in _execute_clauseelement
    ret = self._execute_context(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1316: in _execute_context
    self._handle_dbapi_exception(
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1510: in _handle_dbapi_exception
    util.raise_(
.local/lib/python3.9/site-packages/sqlalchemy/util/compat.py:182: in raise_
    raise exception
.local/lib/python3.9/site-packages/sqlalchemy/engine/base.py:1276: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0xffff903a49a0>
cursor = <cursor object at 0xffff8d49ee50; closed: -1>
statement = 'SELECT xcom.value AS xcom_value \nFROM xcom \nWHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.da...xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC \n LIMIT %(param_1)s'
parameters = {'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'key_1': 'media_type', 'param_1': 1, ...}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0xffff8d457640>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "xcom" does not exist
E       LINE 2: FROM xcom 
E                    ^
E       
E       [SQL: SELECT xcom.value AS xcom_value 
E       FROM xcom 
E       WHERE xcom.key = %(key_1)s AND xcom.task_id = %(task_id_1)s AND xcom.dag_id = %(dag_id_1)s AND xcom.execution_date = %(execution_date_1)s ORDER BY xcom.execution_date DESC, xcom.timestamp DESC 
E        LIMIT %(param_1)s]
E       [parameters: {'key_1': 'media_type', 'task_id_1': 'stage_oldest_tsv_file', 'dag_id_1': 'adhoc_airflow', 'execution_date_1': datetime.datetime(2016, 1, 1, 0, 0, tzinfo=Timezone('UTC')), 'param_1': 1}]
E       (Background on this error at: http://sqlalche.me/e/13/f405)

.local/lib/python3.9/site-packages/sqlalchemy/engine/default.py:608: ProgrammingError
=========================== short test summary info ============================
FAILED tests/dags/util/test_operator_util.py::test_get_dated_main_runner_handles_zero_shift
FAILED tests/dags/util/test_operator_util.py::test_get_dated_main_runner_handles_day_shift
FAILED tests/dags/util/loader/test_paths.py::test_stage_oldest_tsv_file_finds_tsv_file
FAILED tests/dags/util/loader/test_paths.py::test_stage_oldest_tsv_file_stages_tsv_file
FAILED tests/dags/util/loader/test_paths.py::test_stage_oldest_tsv_file_removes_staged_file_from_output_dir
FAILED tests/dags/util/loader/test_paths.py::test_stage_oldest_tsv_file_stages_older_file
FAILED tests/dags/util/loader/test_paths.py::test_stage_oldest_tsv_file_ignores_newer_file
FAILED tests/dags/util/loader/test_sql.py::test_create_loading_table_creates_table
FAILED tests/dags/util/loader/test_sql.py::test_create_loading_table_errors_if_run_twice_with_same_id
FAILED tests/dags/util/loader/test_sql.py::test_drop_load_table_drops_table
================== 10 failed, 682 passed in 78.26s (0:01:18) ===================

Comment on lines -43 to -46
CMD python wait_for_db.py && \
airflow db init && \
airflow users create -r Admin -u airflow -f Air -l Flow -p airflow --email airflow@example.org && \
(airflow scheduler & airflow webserver)
Copy link
Member

Choose a reason for hiding this comment

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

❤️

@AetherUnbound
Copy link
Contributor Author

This all looks great but I have some test failures locally that I'm curious about.

Ah shoot, I didn't specify that the containers need to be rebuilt. Let me add that to the instructions (you'll need to run just build).

@zackkrida
Copy link
Member

This all looks great but I have some test failures locally that I'm curious about.

Ah shoot, I didn't specify that the containers need to be rebuilt. Let me add that to the instructions (you'll need to run just build).

@AetherUnbound yep, thanks for the reminder! Tests pass now.

@@ -53,7 +53,7 @@ lint:
pre-commit run --all-files

# Mount the tests directory and run a particular command
@_mount-tests command: up
@_mount-tests command: (up "postgres s3")
Copy link
Member

Choose a reason for hiding this comment

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

I didn't know it was possible to pass args here!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

just can do so much! 🤯 I just wish it was easier to find stuff in their documentation...lol

Openverse PRs automation moved this from Needs review to Reviewer approved Oct 26, 2021
@AetherUnbound AetherUnbound merged commit 7ee6245 into main Oct 26, 2021
Openverse PRs automation moved this from Reviewer approved to Merged! Oct 26, 2021
@AetherUnbound AetherUnbound deleted the feature/entrypoint#227 branch October 26, 2021 18:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🤖 aspect: dx Concerns developers' experience with the codebase ✨ goal: improvement Improvement to an existing user-facing feature
Projects
No open projects
Openverse PRs
  
Merged!
Development

Successfully merging this pull request may close these issues.

Create a Docker entrypoint for the webserver
3 participants