【发布时间】:2020-04-21 08:44:03
【问题描述】:
我正在关注 TestDriven.io 的 Python/TDD/Docker 教程。
我构建了一个自定义映像,我想对其进行测试。我不能(我想,我是 Docker 和 Python 的菜鸟,请耐心等待)。
这是图像:registry.gitlab.com/sineverba/warehouse:latest。它之所以有效,是因为我成功部署到 Heroku。
我不想用 docker-compose 来测试最终的图像,所以我尝试这样做:
docker network create -d bridge flask-tdd-net
export DATABASE_TEST_URL=postgres://postgres:postgres@flask-tdd-net:5432/users_dev
docker run -d --name app -e "PORT=8765" -p 5002:8765 --network=flask-tdd-net registry.gitlab.com/sineverba/warehouse:latest
docker run -d --name db -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=users_dev -p 5432:5432 --network=flask-tdd-net postgres:12-alpine
我可以启动一个简单的
docker exec app python -V 并获取版本,例如。
但是当我启动时
docker exec app python -m pytest "project/tests"
我明白了(拆分,这里的完整日志:https://pastebin.com/tYjn65ys)
self = <[AttributeError("'NoneType' object has no attribute 'drivername'") raised in repr()] SQLAlchemy object at 0x7fc74676e7f0>
app = <Flask 'project'>, sa_url = None, options = {}
def apply_driver_hacks(self, app, sa_url, options):
"""This method is called before engine creation and used to inject
driver specific hacks into the options. The `options` parameter is
a dictionary of keyword arguments that will then be used to call
the :func:`sqlalchemy.create_engine` function.
The default implementation provides some saner defaults for things
like pool sizes for MySQL and sqlite. Also it injects the setting of
`SQLALCHEMY_NATIVE_UNICODE`.
"""
> if sa_url.drivername.startswith('mysql'):
E AttributeError: 'NoneType' object has no attribute 'drivername'
我也尝试过(在停止和删除容器并重新创建数据库之后)
export DATABASE_TEST_URL=postgres://postgres:postgres@db:5432/users
因此,将名称从 users_dev 转移到 users。
完整的回购链接:https://github.com/sineverba/flask-tdd-docker/tree/add-gitlab-warehouse
提前谢谢你!
编辑
我更改了 env 导致链接 db 错误。这些是新命令,但出现相同的错误。我也尝试导出两个环境,但没有成功。
docker network create -d bridge flask-tdd-net
export DATABASE_TEST_URL=postgres://postgres:postgres@db:5432/users
export DATABASE_URL=postgres://postgres:postgres@db:5432/users
docker run -d --name app -e "PORT=8765" -p 5002:8765 --network=flask-tdd-net registry.gitlab.com/sineverba/warehouse:latest
docker run -d --name db -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=users -p 5432:5432 --network=flask-tdd-net postgres:12-alpine
docker exec app python -m pytest "project/tests"
docker container stop app && docker container rm app && docker container stop db && docker container rm db
开始示例
这是来自 Gitlab 集成的 testdriven.io 示例(我不想使用)。只有为应用导出的 env 是 DATABASE_TEST_URL
image: docker:stable
stages:
- build
- test
variables:
IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}
build:
stage: build
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
script:
- docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $IMAGE:latest || true
- docker build
--cache-from $IMAGE:latest
--tag $IMAGE:latest
--file ./Dockerfile.prod
"."
- docker push $IMAGE:latest
test:
stage: test
image: $IMAGE:latest
services:
- postgres:latest
variables:
POSTGRES_DB: users
POSTGRES_USER: runner
POSTGRES_PASSWORD: runner
DATABASE_TEST_URL: postgres://runner:runner@postgres:5432/users
script:
- pytest "project/tests" -p no:warnings
- flake8 project
- black project --check
- isort project/**/*.py --check-only
已解决
报错是需要导出docker命令里面的变量:
docker run -d --name app -e "PORT=8765" -p 5002:8765 -e "DATABASE_TEST_URL=postgres://postgres:postgres@db:5432/users" --network=flask-tdd-net registry.gitlab.com/sineverba/warehouse:latest
【问题讨论】:
-
您的本地环境中只有
DATABASE_TEST_URL。您的应用程序是否还使用多个 env var 来决定要连接到哪个数据库?我怀疑你在 in Docker 运行应用程序时想要-e "DATABASE_URL=..."。 -
@jonrsharpe 从开始的示例中,只有导出的 ENV VAR 是 DATABASE_TEST_URL。我还复制了示例开始(取自 Gitlab 集成)。没有其他 var 向开发环境发出信号。
标签: python postgresql docker flask