1
\$\begingroup\$

I have a FastAPI app that uses Celery and depends on DB transactions. I'm a little confused as to where the DB transaction should occur--Whether it should be run inside the Celery task definition, or whether it should be run in the endpoint (route) definition. I expect this endpoint to be simultaneously, potentially, so I need the event to not delay significantly but rather be added to a queue, hence the celery.

Transacting in the route definition:

@router.get("/user-form/")
def user_signup(session: Session = Depends(get_db_session)):
    try:
        username = random_username()
        user = User(
            username=f'{username}',
            email=f'{username}@test.com',
        )
        session.add(user)
        session.commit()
    except Exception as e:
        session.rollback()
        raise

    return {"message": "done"}

Or run the DB transaction in a Celery task:

@router.get("/user-form/")
def user_signup(session: Session = Depends(get_db_session)):
    try:
        username = random_username()
        user = User(
            username=f'{username}',
            email=f'{username}@test.com',
        )
        insert_user.delay(user) #<--Enqueue to Celery here
    except Exception as e:
        session.rollback()
        raise

    return {"message": "done"}

# Celery
@shared_task()
def insert_user(user):
    from project.users.models import User

    with db_context() as session:
        try:
           session.add(user)
           session.commit()
        except Exception as e:
           session.rollback()
           raise

I'd like the DB transactions to be in a queue in case they pile up and I need to prevent app delays. Thank you for your suggestions.

New contributor
RichardS is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$
3
  • \$\begingroup\$ Welcome to Code Review! Please edit your question so that the title describes the purpose of the code, rather than its mechanism. We really need to understand the motivational context to give good reviews. Thanks! \$\endgroup\$ 2 days ago
  • \$\begingroup\$ Just throwing in my $0.02; decoupling the user insertion logic from the HTTP server logic will have great benefits (ignoring the context of Celery). Say you want to develop a CLI for your app in the future; now your user signup command can easily be implemented because the insertion logic is decoupled. Also, unit testing. \$\endgroup\$
    – Luke Carr
    2 days ago
  • \$\begingroup\$ @LukeCarr Interesting idea. So I could extract all the transactional logic into a separate transaction method, then the API could call to it through the Celery task. Thanks for the suggestion. \$\endgroup\$
    – RichardS
    2 days ago

Your Answer

RichardS is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.