__init__.py 中的 google.cloud 命名空间导入错误

Posted

技术标签:

【中文标题】__init__.py 中的 google.cloud 命名空间导入错误【英文标题】:google.cloud namespace import error in __init__.py 【发布时间】:2020-07-02 14:27:38 【问题描述】:

我已经阅读了至少十几个不同的 *** 问题,这些问题都提出了相同的基本问题并且具有相同的基本答案:模块未正确安装或 OP 导入错误。

在这种情况下,我正在尝试做from google.cloud import secretmanager_v1beta1

当我运行 airflow dags 或运行 pytest tests/dags/test_my_dag.py 时,它在我的气流容器中工作。但是,如果我运行 cd dags; python -m my_dagcd dags; python my_dag.py 我会收到此错误:

from google.cloud import secretmanager as secretmanager
ImportError: cannot import name 'secretmanager' from 'google.cloud' (unknown location)

我可以在该行正上方的行中添加from google.cloud import bigquery,这样就可以了。从字面上看,这似乎只是这个特定软件包的一个问题。

pytest 和气流命令是否成功为什么重要?因为,我有另一个环境,我试图从命令行运行数据流作业,我得到了同样的错误。不幸的是,出于多种原因,我认为我无法在该环境中绕过此错误。

更新 6

我已将错误范围缩小到google.cloud 命名空间和__init__.py 文件中该命名空间内的secretmanager 包的问题。

如果我将from google.cloud import secretmanager 添加到airflow/dags/__init__.py,然后尝试运行python -m dags.my_dag.py,我会收到此错误,但堆栈跟踪略有不同:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/runpy.py", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/usr/local/lib/python3.7/runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "/workspace/airflow/dags/__init__.py", line 3, in <module>
    from google.cloud import secretmanager
ImportError: cannot import name 'secretmanager' from 'google.cloud' (unknown location)

旧信息

我 95% 确定它仍然是路径问题,并且 pytest 和气流正在修复我不知道的问题,当我尝试手动运行 python 脚本时没有处理。

我尝试过的事情:

cd /airflow; python setup.py develop --user
cd /airflow; pip install -e . --user
cd /airflow/dags; pip install -r requirements.txt --user

更新

根据cmets中的要求,这里是requirements.txt的内容:

boto3>=1.7.84
google-auth==1.11.2
google-cloud-bigtable==1.2.1
google-cloud-bigquery==1.24.0
google-cloud-spanner==1.14.0
google-cloud-storage==1.26.0
google-cloud-logging==1.14.0
google-cloud-secret-manager>=0.2.0
pycloudsqlproxy>=0.0.15
pyconfighelper>=0.0.7
pymysql==0.9.3
setuptools==45.2.0
six==1.14.0

我不小心在上面的 pip 和 python 安装命令示例中省略了 --user 标志。在我的容器环境中,所有内容都使用 --userNOT 在全局 site-packages 目录中安装到用户的主目录中。

更新 2

我已将以下代码添加到生成错误的文件中:

print('***********************************************************************************')
import sys
print(sys.path)
from google.cloud import secretmanager_v1beta1 as secretmanager
print('secretmanager.__file__: '.format(secretmanager.__file__))

来自airflow list_dags

['/home/app/.local/bin', '/usr/local/lib/python37.zip', '/usr/local/lib/python3.7', '/usr/local/lib/python3.7/lib-dynload', '/home/app/.local/lib/python3.7/site-packages', '/home/app/.local/lib/python3.7/site-packages/Jeeves-0.0.1-py3.7.egg', '/home/app/.local/lib/python3.7/site-packages/google_cloud_secret_manager-0.2.0-py3.7.egg', '/home/app/.local/lib/python3.7/site-packages/pyconfighelper-0.0.7-py3.7.egg', '/home/app/.local/lib/python3.7/site-packages/click-7.1.1-py3.7.egg', '/workspace/airflow', '/usr/local/lib/python3.7/site-packages', '/workspace/airflow/dags', '/workspace/airflow/config', '/workspace/airflow/plugins']
secretmanager.__file__: /home/app/.local/lib/python3.7/site-packages/google_cloud_secret_manager-0.2.0-py3.7.egg/google/cloud/secretmanager_v1beta1/__init__.py

来自python my_dag.py

['/workspace/airflow/dags', '/usr/local/lib/python37.zip', '/usr/local/lib/python3.7', '/usr/local/lib/python3.7/lib-dynload', '/home/app/.local/lib/python3.7/site-packages', '/home/app/.local/lib/python3.7/site-packages/Jeeves-0.0.1-py3.7.egg', '/home/app/.local/lib/python3.7/site-packages/google_cloud_secret_manager-0.2.0-py3.7.egg', '/home/app/.local/lib/python3.7/site-packages/pyconfighelper-0.0.7-py3.7.egg', '/home/app/.local/lib/python3.7/site-packages/click-7.1.1-py3.7.egg', '/home/app/.local/lib/python3.7/site-packages/icentris_ml_airflow-0.0.0-py3.7.egg', '/usr/local/lib/python3.7/site-packages']

更新 3 tree airflow/dags

airflow/dags
├── __init__.py
├── __pycache__
│   ├── __init__.cpython-37.pyc
│   ├── bq_to_cs.cpython-37.pyc
│   ├── bq_to_wrench.cpython-37.pyc
│   ├── fetch_cloudsql_tables-bluesun.cpython-37.pyc
│   ├── fetch_cloudsql_tables.cpython-37.pyc
│   ├── fetch_app_tables-bluesun.cpython-37.pyc
│   ├── fetch_app_tables.cpython-37.pyc
│   ├── gcs_to_cloudsql.cpython-37.pyc
│   ├── gcs_to_s3.cpython-37.pyc
│   ├── lake_to_staging.cpython-37.pyc
│   ├── schedule_dfs_sql_to_bq-bluesun.cpython-37.pyc
│   ├── schedule_dfs_sql_to_bq.cpython-37.pyc
│   ├── app_to_bq_initial_load-bluesun.cpython-37.pyc
│   ├── app_to_lake-bluesun.cpython-37.pyc
│   └── app_to_lake.cpython-37.pyc
├── bq_to_wrench.py
├── composer_variables.json
├── my_ml_airflow.egg-info
│   ├── PKG-INFO
│   ├── SOURCES.txt
│   ├── dependency_links.txt
│   └── top_level.txt
├── lake_to_staging.py
├── libs
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── checkpoint.cpython-37.pyc
│   │   └── utils.cpython-37.pyc
│   ├── checkpoint.py
│   ├── io
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   └── __init__.cpython-37.pyc
│   │   └── gcp
│   │       ├── __init__.py
│   │       ├── __pycache__
│   │       │   ├── __init__.cpython-37.pyc
│   │       │   └── storage.cpython-37.pyc
│   │       └── storage.py
│   ├── shared -> /workspace/shared/
│   └── utils.py
├── requirements.txt
├── table_lists
│   └── table-list.json
└── templates
    └── sql
        ├── lake_to_staging.contacts.sql
        ├── lake_to_staging.orders.sql
        └── lake_to_staging.users.sql

11 directories, 41 files

更新 4

我尝试修复它,使 sys.path 在运行 python dags/my_dag.py 时看起来与运行 airflow list_dagspytest test_my_dag.py 时相同。

仍然得到同样的错误。

查看更新版本的文档,我注意到您应该能够做到from google.cloud import secretmanager。这给了我相同的结果(适用于气流和 pytest,而不是在尝试直接运行时)。

在这一点上,我最好的猜测是它与命名空间魔法有关,但我不确定?

【问题讨论】:

你的requirement.txt文件的内容是什么? 试试pip install -U google-cloud-secret-manager。将google-cloud-secret-manager==0.2.0 添加到 requirements.txt。 请在添加其他信息时发表评论,我们不会收到修改通知。 在有效的那个中,secretmanager.__file__ 是什么?在没有的那个中,sys.path 是什么? @DustinIngram 根据您的评论发布更新。谢谢。 【参考方案1】:

必须通过终端安装:pip install google-cloud-secret-manager 因为包名不是 secretmanager 而是 google-cloud-secret-manager

【讨论】:

【参考方案2】:

经过反复试验,问题是如果之前没有从 google.cloud 导入另一个包,则目前无法从 google.cloud 命名空间导入 secretmanager。

例如

mod.py

from google.cloud import secretmanager # Fails with error

mod2.py

from google.cloud import bigquery
from google.cloud import secretmanager # Works because the first import initialized the namespace

【讨论】:

【参考方案3】:

类似于 Noah 的回答,这为我解决了这个问题,而无需导入不需要的模块:

import google.cloud.secretmanager as secretmanager

【讨论】:

【参考方案4】:

我正在使用 Python 3.8.2 和 google-cloud-secret-manager 2.7.1。以下行为我解决了这个问题:

from google.cloud import secretmanager_v1beta1 as secretmanager

【讨论】:

以上是关于__init__.py 中的 google.cloud 命名空间导入错误的主要内容,如果未能解决你的问题,请参考以下文章

包 __init__.py 的相对导入

从__init__.py中的函数导入模块将模块对象绑定到全局命名空间?

加载 __init__.py 时,有没有办法自动导入我文件夹中的所有模型?

__init__.py 中的 google.cloud 命名空间导入错误

Python __init__.py 作用详解

Python __init__.py 作用详解