Einfügen einer weiteren Datei in die Dataflow Python-Flex-Vorlage ImportError
Gibt es ein Beispiel für eine Python Dataflow Flex-Vorlage mit mehr als einer Datei, in die das Skript andere Dateien importiert, die im selben Ordner enthalten sind?
Meine Projektstruktur sieht folgendermaßen aus:
├── pipeline
│ ├── __init__.py
│ ├── main.py
│ ├── setup.py
│ ├── custom.py
Ich versuche, custom.py in main.py für eine Datenfluss-Flex-Vorlage zu importieren.
Ich erhalte den folgenden Fehler bei der Pipeline-Ausführung:
"ModuleNotFoundError: No module named 'custom'"
Die Pipeline funktioniert einwandfrei, wenn ich den gesamten Code in eine einzelne Datei einbinde und keine Importe durchführe.
Beispiel Dockerfile:
FROM gcr.io/dataflow-templates-base/python3-template-launcher-base
ARG WORKDIR=/dataflow/template/pipeline
RUN mkdir -p ${WORKDIR} WORKDIR ${WORKDIR}
COPY pipeline /dataflow/template/pipeline
COPY spec/python_command_spec.json /dataflow/template/
ENV DATAFLOW_PYTHON_COMMAND_SPEC /dataflow/template/python_command_spec.json
RUN pip install avro-python3 pyarrow==0.11.1 apache-beam[gcp]==2.24.0
ENV FLEX_TEMPLATE_PYTHON_SETUP_FILE="${WORKDIR}/setup.py" ENV FLEX_TEMPLATE_PYTHON_PY_FILE="${WORKDIR}/main.py"
Python-Spezifikationsdatei:
{
"pyFile":"/dataflow/template/pipeline/main.py"
}
Ich stelle die Vorlage mit dem folgenden Befehl bereit: gcloud builds submit --project=${PROJECT} --tag ${TARGET_GCR_IMAGE} .
Jede Hilfe wird geschätzt.
Antworten
Ich habe dies tatsächlich gelöst, indem ich einen zusätzlichen Parameter setup_file an die Vorlagenausführung übergeben habe. Außerdem müssen setup_fileParameter zu den Vorlagenmetadaten hinzugefügt werden
--parameters setup_file="/dataflow/template/pipeline/setup.py"
Anscheinend ist der Befehl ENV FLEX_TEMPLATE_PYTHON_SETUP_FILE="${WORKDIR}/setup.py" in der Docker-Datei nutzlos und nimmt die Setup-Datei nicht auf.
Meine Setup-Datei sah folgendermaßen aus:
import setuptools
setuptools.setup(
packages=setuptools.find_packages(),
install_requires=[
'apache-beam[gcp]==2.24.0'
],
)
Nach einigen Tests stellte ich fest, dass Phyton-Dateien im Arbeitsverzeichnis ( WORKDIR) aus unbekannten Gründen nicht mit einem Import referenziert werden können. Es funktioniert jedoch, wenn Sie einen Unterordner erstellen und die Python-Abhängigkeiten in diesen verschieben. Ich habe getestet und es hat funktioniert. In Ihrem Anwendungsfall können Sie beispielsweise die folgende Struktur haben:
├── pipeline
│ ├── main.py
│ ├── setup.py
│ ├── mypackage
│ │ ├── __init__.py
│ │ ├── custom.py
Und Sie können referenzieren : import mypackage.custom. Die Docker-Datei sollte in das custom.pyrichtige Verzeichnis verschoben werden .
RUN mkdir -p ${WORKDIR}/mypackage RUN touch ${WORKDIR}/mypackage/__init__.py
COPY custom.py ${WORKDIR}/mypackage
Und die Abhängigkeit wird dem Python-Installationsverzeichnis hinzugefügt:
$ docker exec -it <container> /bin/bash
# find / -name custom.py
/usr/local/lib/python3.7/site-packages/mypackage/custom.py
@ pavan-kumar-kattamuri hat mich gebeten, meine Lösung zu veröffentlichen, also hier ist sie.
FROM gcr.io/dataflow-templates-base/python3-template-launcher-base:flex_templates_base_image_release_20210120_RC00
ARG WORKDIR=/dataflow/template
RUN mkdir -p ${WORKDIR} WORKDIR ${WORKDIR}
COPY requirements.txt .
# Read https://stackoverflow.com/questions/65766066/can-i-make-flex-template-jobs-take-less-than-10-minutes-before-they-start-to-pro#comment116304237_65766066
# to understand why apache-beam is not being installed from requirements.txt
RUN pip install --no-cache-dir -U apache-beam==2.26.0
RUN pip install --no-cache-dir -U -r ./requirements.txt
COPY mymodule.py setup.py ./
COPY protoc_gen protoc_gen/
ENV FLEX_TEMPLATE_PYTHON_REQUIREMENTS_FILE="${WORKDIR}/requirements.txt" ENV FLEX_TEMPLATE_PYTHON_PY_FILE="${WORKDIR}/mymodule.py"
ENV FLEX_TEMPLATE_PYTHON_SETUP_FILE="${WORKDIR}/setup.py"
und hier ist meine setup.py:
import setuptools
setuptools.setup(
packages=setuptools.find_packages(),
install_requires=[],
name="my df job modules",
)