Reputation: 101
In our project, we came across the fact that we need to compile an application in python using Nuitka. This application is a simple crud. There is nothing complicated about it. However, along with the launch of the application, alembic migrations are also launched. That's where the problem arose. We want to deploy the application together with migrations in a single binary file (python code is not allowed in our container). Roughly speaking, main.py looks like this:
from alembic.config import Config
from alembic import command
def run_application() -> None:
return None
if __name__ == "__main__":
alembic_cfg = Config("alembic.ini")
command.upgrade(alembic_cfg, "head")
run_application()
That is, alembic migrations are launched first, and then our application. Now to the heart of the problem. Nuitka converts python code to C and then compiles it. In order to convert and execute the code, it must be imported. However, alembic works differently. This library scans the folder with migrations and converts them into modules, and then executes: there are no direct imports. Here is the function by which migrations are read:
def load_python_file(dir_: str, filename: str) -> ModuleType:
"""Load a file from the given path as a Python module."""
module_id = re.sub(r"\W", "_", filename)
path = os.path.join(dir_, filename)
_, ext = os.path.splitext(filename)
if ext == ".py":
if os.path.exists(path):
module = load_module_py(module_id, path)
else:
pyc_path = pyc_file_from_path(path)
if pyc_path is None:
raise ImportError("Can't find Python file %s" % path)
else:
module = load_module_py(module_id, pyc_path)
elif ext in (".pyc", ".pyo"):
module = load_module_py(module_id, path)
else:
assert False
return module
It converts a python file into a module and then alembic works with it.The commercial version of nuitka has embedded files (which are embedded inside a binary file). This will solve the problem: we can put a folder with migrations inside the binary file. However, I would like to try to assemble it more correctly. Does anyone have any ideas?
Upvotes: 3
Views: 65