question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow SQLAlchemy factories to be committed on create

See original GitHub issue

It seems like the general consensus is that one should only flush the current session during a test case, and roll back on each tear down. Due to the nature of my testing setup it is more convenient to commit instead of flush on create. Have you considered adding a meta flag similar to force_flush that would allow the session to be committed?

for example:

class SQLAlchemyModelFactory(base.Factory):
    """Factory for SQLAlchemy models. """

    _options_class = SQLAlchemyOptions
    class Meta:
        abstract = True

    @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
        obj = model_class(*args, **kwargs)
        session.add(obj)
+       if cls._meta.force_commit:
+          session.commit()
        elif cls._meta.force_flush:
            session.flush()
        return obj

overriding SQLAlchemyModelFactory._create is my current solution. Any suggestions on how to properly have Factories be committed on creation is welcome! Thanks!

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:22 (19 by maintainers)

github_iconTop GitHub Comments

1reaction
aalvrzcommented, Feb 16, 2021

@zyskowsk I’ve been following this thread because I am experiencing a similar issue:

class MyModel(Base):
    created_at = Column(DateTime, nullable=False, default=datetime.utcnow)


class MyFactory(factory.alchemy.SQLAlchemyModelFactory):
    class Meta:
        model = MyModel
        sqlalchemy_session_persistence = "commit"


def my_test():
    a = MyFactory()
    b = MyFactory()
    c = MyFactory()

    assert not a.created_at == b.created_at  # Fails

All those objects will have the same value for created_at. I am using commit for sqlalchemy_session_persistence and the assertion fails. However if I use flush then the datetimes will be different. Not realy sure what strategy I should use? From what I understand in this thread, your intention was to use commit strategy.

1reaction
zyskowskcommented, Jun 23, 2016

Hey @jeffwidman thanks for the quick response! enabling force_flush is not exactly what I am looking for. Let me try and better explain my situation, I may be missing something simple.

The situation I am running into is that I have server-side defaults on all of my models for created_at and updated_at. These defaults are set with db.func.now() in postgres, which is defined by the start time of the last transaction.

This means that if I only ever call session.flush(), even if I issue an INSERT followed by an UPDATE, on the same row, the updated_at value will remain the same until the current transaction is committed.

I am hoping to test that when I update an object through an api, the updated_at value changes. However, when I create a factory with force_flush enabled, and then issue an update on that row late, the updated_at column still reflects the start time of the open transaction.

For this reason I want Factory.create call to issue a commit on the session, not just a flush.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I setup dependent factories using Factory Boy and ...
The User schema requires a Group foreign key when creating a new user. Since the Group primary key is assigned from the database,...
Read more >
Session Basics — SQLAlchemy 2.0 Documentation
When you write your application, the sessionmaker factory should be scoped the same as the Engine object created by create_engine() , which is ......
Read more >
SQLAlchemy + FactoryBoy: Passing arbitrary sessions to ...
SQLAlchemy + FactoryBoy: Passing arbitrary sessions to factories ... in a separate session and creating a DbUtils class to handle sessions ...
Read more >
Python Transactional Tests Using SQL Alchemy, Pytest, and ...
We want to be able to use factories to easily create test objects. We do not want any issues and interference between the...
Read more >
Use the Amazon Redshift SQLAlchemy dialect to interact with ...
We build the SQLAlchemy URL as shown in the following code. URL.create() is available for SQLAlchemy version 1.4 and above. When authenticating ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found