BeanieODM / beanie

Asynchronous Python ODM for MongoDB
http://beanie-odm.dev/
Apache License 2.0
1.91k stars 201 forks source link

[BUG] ModuleNotFoundError when importing models in a migration module #895

Closed VKTB closed 4 months ago

VKTB commented 4 months ago

Describe the bug Inside the models package, which is inside the test_api package, I have an employee.py module where my EmployeeDocument and OldEmployeeDocument classes (along with other Pydantic models) are defined. Inside the models package, I also have the migrations package where I keep my migration modules (20240301112216_employee-address.py in this case). The migration module imports the EmployeeDocument and OldEmployeeDocument classes from the employee.py module but ModuleNotFoundError: No module named 'test_api.models' is raised when I run:

beanie migrate -uri 'mongodb://user:pass@host' -db db -p test_api/models/migrations/ --distance 1 --no-use-transaction

To Reproduce

from beanie import iterative_migration

from test_api.models.employee import OldEmployeeDocument, EmployeeDocument

class Forward:
    @iterative_migration()
    async def address_obj_to_str(self, input_document: OldEmployeeDocument, output_document: EmployeeDocument):
        output_document.address = (f"{input_document.address.street}, {input_document.address.town}, "
                                   f"{input_document.address.postcode}")

class Backward:
    @iterative_migration()
    async def address_str_to_obj(self, input_document: EmployeeDocument, output_document: OldEmployeeDocument):
        street, town, postcode = input_document.address.split(", ")
        output_document.address.street = street
        output_document.address.town = town
        output_document.address.postcode = postcode

Project directory structure:

test-api
  |-test_api
  |  |-main.py
  |  |-models
  |  |  |-employee.py
  |  |  |-migrations
  |  |  |  |-20240306152516_employee-address.py
  |  |  |  |-__init__.py
  |  |  |-__init__.py
  |  |-__init__.py

Expected behavior It should not fail to import the modules.

Additional context Python version: 3.12.2 OS: Windows 10 Logs:

Building migration list
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\programming\test-api\venv\Scripts\beanie.exe\__main__.py", line 7, in <module>
  File "C:\programming\test-api\venv\Lib\site-packages\click\core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\programming\test-api\venv\Lib\site-packages\click\core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "C:\programming\test-api\venv\Lib\site-packages\click\core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\programming\test-api\venv\Lib\site-packages\click\core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\programming\test-api\venv\Lib\site-packages\click\core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\programming\test-api\venv\Lib\site-packages\beanie\executors\migrate.py", line 200, in migrate
    asyncio.run(run_migrate(settings))
  File "C:\Python312\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\asyncio\base_events.py", line 685, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\programming\test-api\venv\Lib\site-packages\beanie\executors\migrate.py", line 110, in run_migrate
    root = await MigrationNode.build(settings.path)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\programming\test-api\venv\Lib\site-packages\beanie\migrations\runner.py", line 222, in build
    ).load_module((path / name).stem)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap_external>", line 649, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 1176, in load_module
  File "<frozen importlib._bootstrap_external>", line 1000, in load_module
  File "<frozen importlib._bootstrap>", line 537, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 966, in _load
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "C:\programming\test-api\test_api\models\migrations\20240301112216_employee-address.py", line 3, in <module>
    from test_api.models.employee import OldEmployeeDocument, EmployeeDocument
ModuleNotFoundError: No module named 'test_api.models'
VKTB commented 4 months ago

Closing as I only just realised that this is a duplicate of https://github.com/roman-right/beanie/issues/186