4
votes

Dans testing.postgresql, impossible de trouver la commande initdb dans Docker

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()


0 commentaires

3 Réponses :


0
votes

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.


2 commentaires

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 :)



0
votes

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


0 commentaires

0
votes

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 .


0 commentaires