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
.