Il y a un fil similaire qui a le même problème mais qui n'a pas pu fonctionner pour moi. En fait, je suis en train de unittest myproject avec testing.postgresql et je suis en l'intérieur d' un conteneur de docker.
Cependant, j'obtiens un RuntimeError: command not found: initdb lorsque RuntimeError: command not found: initdb ma commande,
docker-compose exec myproject python3 -m unittest
Cela fonctionne dans WSL mais pas dans le menu fixe.
On dirait qu'il n'est pas en mesure de trouver initdb. Y a-t-il des problèmes de conflit avec la base de données créée dans docker-compose.yml ou est-ce que je manque des lignes dans les fichiers docker?
Je décris mon test comme exemple de la documentation :
ImportError: Failed to import test module: tests.testMyproject
File "/usr/local/lib/python3.7/unittest/loader.py", line 436, in _find_test_path
module = self._get_module_from_name(name)
File "/usr/local/lib/python3.7/unittest/loader.py", line 377, in _get_module_from_name
__import__(name)
File "/code/tests/testmyProject.py", line 40, in <module>
class TestPostgresqlInteraction(unittest.TestCase):
File "/code/tests/testmyProject.py", line 46, in TestPostgresqlInteraction
Postgresql = testing.postgresql.PostgresqlFactory(cache_initialized_db=True)
File "/usr/local/lib/python3.7/site-packages/testing/common/database.py", line 52, in __init__
self.cache = self.target_class(**settings_noautostart)
File "/usr/local/lib/python3.7/site-packages/testing/common/database.py", line 92, in __init__
self.initialize()
File "/usr/local/lib/python3.7/site-packages/testing/postgresql.py", line 50, in initialize
self.initdb = find_program('initdb', ['bin'])
File "/usr/local/lib/python3.7/site-packages/testing/postgresql.py", line 144, in find_program
raise RuntimeError("command not found: %s" % name)
RuntimeError: command not found: initdb
docker-compose.yml
FROM postgres:11.3 WORKDIR /secrets COPY secrets/dbUser.txt dbUser.txt COPY secrets/dbPassword.txt dbPassword.txt RUN mkdir -p /docker-entrypoint-initdb.d COPY database/schema.sql /docker-entrypoint-initdb.d
myproject / Dockerfile
FROM python:3.7.3-stretch
RUN apt-get update && apt-get install -y \
poppler-utils
ARG moduleDir=myproject
WORKDIR /code
COPY secrets/ /secrets
# COPY $moduleDir/myproject/ ./
COPY $moduleDir/requirements.txt requirements.txt
RUN pip install -r requirements.txt
base de données / Dockerfile
version: "3"
services:
myproject:
build:
context: .
dockerfile: ./myproject/Dockerfile
depends_on:
- database
volumes:
- ./myproject:/code
stdin_open: true
tty: true
database:
build:
context: .
dockerfile: ./database/Dockerfile
environment:
POSTGRES_USER_FILE: /secrets/dbUser.txt
POSTGRES_PASSWORD_FILE: /secrets/dbPassword.txt
ports:
- "8765:5432"
volumes:
- otherdata:/var/lib/postgresql/data
Traceback:
class TestPostgresqlInteraction(unittest.TestCase):
Postgresql = testing.postgresql.PostgresqlFactory(cache_initialized_db=True)
with testing.postgresql.Postgresql() as postgresql:
engine = create_engine(postgresql.url())
dbConn = psycopg2.connect(**postgresql.dsn())
cursor = dbConn.cursor()
def setUp(self):
self.postgresql = self.Postgresql()
def tearDown(self):
self.postgresql.stop()
def testMethod(self)
conn = psycopg2.connect(**self.postgresql.dsn())
cursor = conn.cursor()
# execute cursor and do tests...
def tearDownModule(self):
self.Postgresql.clear_cache()
3 Réponses :
L'utilisation de testing.postgresql signifie que vous obtiendrez une nouvelle instance de PG préparée par l'outil - comme cela est décrit dans leur documentation . Ce que vous devez faire est de pointer vers cet autre docker. Utilisez simplement psycopg et connectez-vous à la database de database :
dsn = "dbname='" + RDS_DBNAME + "' user='" + RDS_USERNAME + "' host='database' password='" + RDS_PASSWORD + "'" dbConn = psycopg2.connect(dsn)
En plus de cela - vous with des regards étranges. Mais cela ne peut être que mon impression.
RDS_DBNAME , RDS_USERNAME , RDS_PASSWORD référence à ce que j'ai défini dans le répertoire secrets/ ?
@resolute - oui RDS_DBNAME est le nom de votre base de données créée par schema.sql , et pour y arriver, vous avez besoin d'informations d'identification, d'utilisateur de dbUser.txt et de mot de passe de dbPassword.txt :)
Votre conteneur Docker peut ne pas avoir la commande which shell.
testing.postgresql appelle testing.common.database.get_path_of , qui exécute ensuite la commande which pour localiser le programme initdb :
def get_path_of(name):
if os.name == 'nt':
which = 'where'
else:
which = 'which'
try:
path = subprocess.Popen([which, name],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()[0]
if path:
return path.rstrip().decode('utf-8')
else:
return None
except Exception:
return None
Si which n'est pas le cas, vous pouvez probablement l'ajouter à l'aide d'un gestionnaire de paquets. Cela a fonctionné sur mon conteneur basé sur CentOS:
yum install which
Pour utiliser testing.postgresql vous devez accéder au serveur postgresql dans votre myproject Docker et pas seulement dans la database Docker. La base de données de test temporaire locale se connectera à l'autre base de données pour obtenir des données, mais cela signifie toujours que vous avez besoin d'une instance locale du serveur postgresql à l'intérieur du myproject.
Dans votre myproject/Dockerfile changez simplement le premier RUN et ajoutez postgresql après poppler-utils .