Description
First Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn't find it.
- I searched the SQLModel documentation, with the integrated search.
- I already searched in Google "How to X in SQLModel" and didn't find any information.
- I already read and followed all the tutorial in the docs and didn't find an answer.
- I already checked if it is not related to SQLModel but to Pydantic.
- I already checked if it is not related to SQLModel but to SQLAlchemy.
Commit to Help
- I commit to help with one of those options 👆
Example Code
# NOTE: all of these classes are contained in separate files. They've been compiled into this list for convenience
from sqlmodel import SQLModel, Field
from typing import List, Optional
from sqlmodel import Field, Relationship
from sqlalchemy import UniqueConstraint
class ManufacturerPerUser(SQLModel, table=True):
__tablename__ = 'manufacturer_per_users'
id: Optional[int] = Field(primary_key=True, nullable=False)
user_id: Optional[int] = Field(
default=None,
nullable=False,
foreign_key='User.id'
)
manufacturer_id: Optional[int] = Field(
default=None,
nullable=False,
foreign_key='Manufacturer.id'
)
class ManufacturerBase(SQLModel):
pass # snipping out extraneous fields
class Manufacturer(ManufacturerBase, table=True):
__tablename__ = 'manufacturers'
id: Optional[int] = Field(primary_key=True, nullable=False)
users: List['Users'] = Relationship(
back_populates='manufacturers',
link_model=ManufacturerPerUser,
sa_relationship_kwargs={'lazy': 'selectin'}
)
class UserBase(SQLModel):
sub: str
pass # snipping out extraneous fields
class User(UserBase, table=True):
__tablename__ = 'users'
__table_args__ = (UniqueConstraint('sub'),)
id: Optional[int] = Field(primary_key=True, nullable=False)
manufacturers: List['Manufacturer'] = Relationship(
back_populates='users',
link_model=ManufacturerPerUser,
sa_relationship_kwargs={'lazy': 'selectin'}
)
Description
I upgraded a project to SQLModel version 0.0.8 and, after that, it started giving out TypeError: cannot pickle 'module' object
on the models that had a many to many relationship through the link_model
Relationship
attribute.
I figured it was the many to many relationship since, after I deleted it from one of the models to test, that particular model stopped erroring out. However, there might be something else I'm missing that's causing the error. Either way, the error seems to happen only when there's a Relationship
attribute with a link_model
for the many to many relation. I even tried to remove the __tablename__
attributes on the tables just in case that was messing something up, but I had no luck.
I tried googling the issue and could not find any solution that would help on any front, so I'm currently at a loss. Closest match was a question where the OP was using SQLAlchemy directly, which I am NOT doing and so the solution proposed did not work for me. Any advice or guidance would be appreciated.
If it helps, I followed this example for the layout (though using PDM instead of Poetry): https://github.com/jonra1993/fastapi-alembic-sqlmodel-async.
Also, note that, before the upgrade to 0.0.8 (we were on 0.0.6 before), the Relationship
attributes were completely non-functional, so they didn't error out (we did the joins manually to obtain the data).
The full error dump looks as such:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
self.run()
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/.venv/lib/python3.11/site-packages/uvicorn/_subprocess.py", line 76, in subprocess_started
target(sockets=sockets)
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/.venv/lib/python3.11/site-packages/uvicorn/server.py", line 60, in run
return asyncio.run(self.serve(sockets=sockets))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "uvloop/loop.pyx", line 1517, in uvloop.loop.Loop.run_until_complete
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/.venv/lib/python3.11/site-packages/uvicorn/server.py", line 67, in serve
config.load()
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/.venv/lib/python3.11/site-packages/uvicorn/config.py", line 477, in load
self.loaded_app = import_from_string(self.app)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/.venv/lib/python3.11/site-packages/uvicorn/importer.py", line 21, in import_from_string
module = importlib.import_module(module_str)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/main.py", line 3, in <module>
from v1 import router as main_router
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/v1/__init__.py", line 1, in <module>
from .main_router import router
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/v1/main_router.py", line 3, in <module>
from .users import router as users_router
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/v1/users/__init__.py", line 1, in <module>
from .router import router
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/v1/users/router.py", line 2, in <module>
from .insert_user import insert_user
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/v1/users/insert_user.py", line 4, in <module>
from core.db.models import User
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/core/db/models/__init__.py", line 1, in <module>
from .User import User
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/core/db/models/User.py", line 8, in <module>
class User(UserBase, table=True):
File "/Users/magnaillusion/Development/SEA/new-system/sea-new-backend/.venv/lib/python3.11/site-packages/sqlmodel/main.py", line 337, in __init__
temp_field = ModelField.infer(
^^^^^^^^^^^^^^^^^
File "pydantic/fields.py", line 506, in pydantic.fields.ModelField.infer
File "pydantic/fields.py", line 436, in pydantic.fields.ModelField.__init__
File "pydantic/fields.py", line 546, in pydantic.fields.ModelField.prepare
File "pydantic/fields.py", line 570, in pydantic.fields.ModelField._set_default_and_type
File "pydantic/fields.py", line 439, in pydantic.fields.ModelField.get_default
File "pydantic/utils.py", line 695, in pydantic.utils.smart_deepcopy
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/copy.py", line 172, in deepcopy
y = _reconstruct(x, memo, *rv)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/copy.py", line 271, in _reconstruct
state = deepcopy(state, memo)
^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/copy.py", line 146, in deepcopy
y = copier(x, memo)
^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/copy.py", line 231, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/copy.py", line 161, in deepcopy
rv = reductor(4)
^^^^^^^^^^^
TypeError: cannot pickle 'module' object```
### Operating System
macOS
### Operating System Details
Currently running Montery, M1 chipset.
### SQLModel Version
0.0.8
### Python Version
3.11.1
### Additional Context
_No response_