Skip to content

SQL Alchemy: TypeError: _save() got multiple values for argument 'session' when model has column named session #775

@fernandoaguilar

Description

@fernandoaguilar

Description

We have a SQLAlchemy model which has a foreign key session_id and a relationship session. Whenever we try creating an instance with factory boy and pass in the session relationship to the factory we get an exception saying that multiple sessions were passed into the _save method in alchemy.py. This makes sense to me but we would like it if this was not the case since everything was working fine in version 2.12.

To Reproduce

Model / Factory code
class MyModel(Base):
    session_id = Column(Integer, ForeignKey('session.id'), index=True, nullable=False)
    session = relationship("Session")

class BaseFactory(SQLAlchemyModelFactory):
    class Meta:
        abstract = True
        sqlalchemy_session = db.session   # the SQLAlchemy session object
        sqlalchemy_session_persistence = 'commit'

class MyModelFactory(BaseFactory):
    class Meta:
        model = MyModel
The issue

Instantiate your factory and pass in the session column kwarg

MyModelFactory(session=some_session_object)

throw this error.

/app/tests/test_models/test_session.py:424: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.tox/python/lib/python3.7/site-packages/factory/base.py:39: in __call__
    return cls.create(**kwargs)
.tox/python/lib/python3.7/site-packages/factory/base.py:527: in create
    return cls._generate(enums.CREATE_STRATEGY, kwargs)
.tox/python/lib/python3.7/site-packages/factory/alchemy.py:51: in _generate
    return super(SQLAlchemyModelFactory, cls)._generate(strategy, params)
.tox/python/lib/python3.7/site-packages/factory/base.py:464: in _generate
    return step.build()
.tox/python/lib/python3.7/site-packages/factory/builder.py:283: in build
    kwargs=kwargs,
.tox/python/lib/python3.7/site-packages/factory/base.py:316: in instantiate
    return self.factory._create(model, *args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'tests.factories.MyModelFactory'>
model_class = <class 'MyModel'>
args = ()
kwargs = {'session': Session 2}
session = <sqlalchemy.orm.scoping.scoped_session object at 0x10a668e50>

    @classmethod
    def _create(cls, model_class, *args, **kwargs):
        """Create an instance of the model, and save it to the database."""
        session = cls._meta.sqlalchemy_session
    
        if session is None:
            raise RuntimeError("No session provided.")
        if cls._meta.sqlalchemy_get_or_create:
            return cls._get_or_create(model_class, session, *args, **kwargs)
>       return cls._save(model_class, session, *args, **kwargs)
E       TypeError: _save() got multiple values for argument 'session'

.tox/python/lib/python3.7/site-packages/factory/alchemy.py:99: TypeError

Notes

An easy solution might be to rename the param to sql_alchemy_session or something more explicit. I'm guessing this will happen to any model with any column named session no matter the type, it could be a simple int or string.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions