0

I'm using SQLALCHEMY 1.4.25 for a project. But I'm having some difficulties.

I'm getting the follow error:

sqlalchemy.exc.TimeoutError: QueuePool limit of size 5 overflow 10 reached, connection timed out, timeout 30.00

I studied a little, and made some adjustments in my code but continuing getting error.

In my code i do many operations in database. And my methods are structured like this:

@staticmethod
def cadastrar_candidato(lista_candidatos, chamada):
    try:
        with Session() as session:

            for candidato in lista_candidatos:

                novo_candidato = CandidatosModel(
                nome_curso = candidato['NO_CURSO'], turno_curso = candidato['DS_TURNO'], modalidade_curso = candidato['DS_FORMACAO'],
                num_insc_enem = candidato['CO_INSCRICAO_ENEM'], nome = candidato['NO_INSCRITO'], cpf = candidato['NU_CPF_INSCRITO'],
                email = candidato['DS_EMAIL'], codigo_curso_inscricao = candidato['CO_CURSO_INSCRICAO'],
                modalidade_concorrencia = candidato['NO_MODALIDADE_CONCORRENCIA'],
                sigla_modalidade_concorrencia = ConversaoModalidadesHelper.conversao_modalidade_para_sigla(candidato['NO_MODALIDADE_CONCORRENCIA']),
                sigla_modalidade_aprovacao = ConversaoModalidadesHelper.conversao_modalidade_para_sigla(candidato['NO_MODALIDADE_CONCORRENCIA']),
                nota_candidato = candidato['NU_NOTA_CANDIDATO'], num_classificacao = candidato['NU_CLASSIFICACAO'],
                chamada_aprovacao = chamada)

                session.add(novo_candidato)

            session.commit()
            session.close()

            return True

    except Exception as e:

        # Em caso de exceção, imprima o erro e retorne False para indicar falha no cadastro
        print(f"Erro ao cadastrar candidato: {str(e)}")
        return False

Has anyone experienced this type of problem and can help me?`

I studied a little, and made some adjustments in my code adding "with" like documentation, but continuing getting error.

As mentioned above, all methods that connect to the database have the same structure.

At project level, I have its structure:

    app_directory
     - modelos
           - CandidatosModel.py
           - UsuariosModel.py
     - relatorios
           - ListaCandidatosRel.py
     - estático
     - modelos
           - index.html
           - outrosarquivos.html
     configurations.py
     app.py

In my configurations.py file I have the following structure:

# Instância da engine
motor = create_engine(db_string)

# Instância do sessionmaker
Session = sessionmaker(bind=engine)

# Defina uma pasta para upload de arquivos
UPLOAD_FOLDER = 'aplicativo/static/arquivos/uploads'

RELATORIOS_FOLDER = '/app/static/files/relatorios_gerados'

IMAGES_FOLDER = 'aplicativo/static/arquivos/img'

SECRECT_KEY = 'chave-secreta-vai-aqui'

SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://postgres:123@127.0.0.1:5433/db_app

The code started to show errors after adding the following snippet to my app.py file

@app.route("/chamadas-subsequentes", methods=['GET', 'POST'])
@login_required
def chamadas_subsequentes():

    if request.method == "POST":    


        todos_os_cursos = CursosAndVagasModel.obter_todos_os_cursos_e_vagas()

        # Obtem número da última chamada executada e adiciona +1 para a próxima
        numero_chamada = ControleChamadasModel.recuperar_ultima_chamada() + 1
        # Faz a inserção da nova chamada na tabela controle_chamadas
        ControleChamadasModel.inserir_item_controle_chamada(numero_chamada)

        # Dicionários de dados utilizados para auxiliar no remanejamento de vagas
        dic_ac = {}
        dic_ri = {}
        dic_ri_cd = {}
        dic_ri_ppi = {}
        dic_ri_ppi_cd = {}
        dic_rs = {}
        dic_rs_cd = {}
        dic_rs_ppi = {}
        dic_rs_ppi_cd = {}

        for curso in todos_os_cursos:

            # Obter quantidade de vagas disponíveis
            vagas_ac = curso.controle_vagas_ac
            vagas_ri = curso.controle_vagas_ri
            vagas_ri_cd = curso.controle_vagas_ri_cd
            vagas_ri_ppi = curso.controle_vagas_ri_ppi
            vagas_ri_ppi_cd = curso.controle_vagas_ri_ppi_cd
            vagas_rs = curso.controle_vagas_rs
            vagas_rs_cd = curso.controle_vagas_rs_cd
            vagas_rs_ppi = curso.controle_vagas_rs_ppi
            vagas_rs_ppi_cd = curso.controle_vagas_rs_ppi_cd

            siglas_modalidade_concorrencia = ['AC', 'RI', 'RI-CD', 'RI-PPI', 'RI-PPI-CD', 'RS', 'RS-CD', 'RS-PPI', 'RS-PPI-CD']

            for sigla in siglas_modalidade_concorrencia:

                if sigla == "AC":
                    consulta_candidatos_que_vao_compor_ac = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_ac, None)

                    qtd_candidatos_que_vao_compor_ac = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_ac)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_ac, numero_chamada)

                    if qtd_candidatos_que_vao_compor_ac < vagas_ac:
                        qtd_vagas_sobraram_ac = vagas_ac - qtd_candidatos_que_vao_compor_ac

                        dic_ac[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_ac
                        }

                elif sigla == "RI":

                    consulta_candidatos_que_vao_compor_ri = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_ri, 'RI')

                    qtd_candidatos_que_vao_compor_ri = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_ri)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_ri, numero_chamada)

                    if qtd_candidatos_que_vao_compor_ri < vagas_ri:
                        qtd_vagas_sobraram_ri = vagas_ri - qtd_candidatos_que_vao_compor_ri

                        dic_ri[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_ri
                        }

                elif sigla == "RI-CD":

                    consulta_candidatos_que_vao_compor_ri_cd = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_ri_cd, 'RI-CD')

                    qtd_candidatos_que_vao_compor_ri_cd = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_ri_cd)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_ri_cd, numero_chamada)

                    if qtd_candidatos_que_vao_compor_ri_cd < vagas_ri_cd:
                        qtd_vagas_sobraram_ri_cd = vagas_ri_cd - qtd_candidatos_que_vao_compor_ri_cd

                        dic_ri_cd[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_ri_cd
                        }

                elif sigla == "RI-PPI":

                    consulta_candidatos_que_vao_compor_ri_ppi = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_ri_ppi, 'RI-PPI')

                    qtd_candidatos_que_vao_compor_ri_ppi = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_ri_ppi)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_ri_ppi, numero_chamada)

                    if qtd_candidatos_que_vao_compor_ri_ppi < vagas_ri_ppi:
                        qtd_vagas_sobraram_ri_ppi = vagas_ri_ppi - qtd_candidatos_que_vao_compor_ri_ppi

                        dic_ri_ppi[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_ri_ppi
                        }

                elif sigla == "RI-PPI-CD":

                    consulta_candidatos_que_vao_compor_ri_ppi_cd = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_ri_ppi_cd, 'RI-PPI-CD')

                    qtd_candidatos_que_vao_compor_ri_ppi_cd = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_ri_ppi_cd)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_ri_ppi_cd, numero_chamada)

                    if qtd_candidatos_que_vao_compor_ri_ppi_cd < vagas_ri_ppi_cd:
                        qtd_vagas_sobraram_ri_ppi_cd = vagas_ri_ppi_cd - qtd_candidatos_que_vao_compor_ri_ppi_cd

                        dic_ri_ppi_cd[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_ri_ppi_cd
                        }

                elif sigla == "RS":

                    consulta_candidatos_que_vao_compor_rs = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_rs, 'RS')

                    qtd_candidatos_que_vao_compor_rs = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_rs)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_rs, numero_chamada)

                    if qtd_candidatos_que_vao_compor_rs < vagas_rs:
                        qtd_vagas_sobraram_rs = vagas_rs - qtd_candidatos_que_vao_compor_rs

                        dic_rs[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_rs
                        }

                elif sigla == "RS-CD":

                    consulta_candidatos_que_vao_compor_rs_cd = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_rs_cd, 'RS-CD')

                    qtd_candidatos_que_vao_compor_rs_cd = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_rs_cd)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_rs_cd, numero_chamada)

                    if qtd_candidatos_que_vao_compor_rs_cd < vagas_rs_cd:
                        qtd_vagas_sobraram_rs_cd = vagas_rs_cd - qtd_candidatos_que_vao_compor_rs_cd

                        dic_rs_cd[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_rs_cd
                        }

                elif sigla == "RS-PPI":

                    consulta_candidatos_que_vao_compor_rs_ppi = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_rs_ppi, 'RS-PPI')

                    qtd_candidatos_que_vao_compor_rs_ppi = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_rs_ppi)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_rs_ppi, numero_chamada)

                    if qtd_candidatos_que_vao_compor_rs_ppi < vagas_rs_ppi:
                        qtd_vagas_sobraram_rs_ppi = vagas_rs_ppi - qtd_candidatos_que_vao_compor_rs_ppi

                        dic_rs_ppi[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_rs_ppi
                        }

                elif sigla == "RS-PPI-CD":

                    consulta_candidatos_que_vao_compor_rs_ppi_cd = CandidatosModel.consultar_candidatos_que_vao_compor_categoria(curso.codigo_curso, vagas_rs_ppi_cd, 'RS-PPI-CD')

                    qtd_candidatos_que_vao_compor_rs_ppi_cd = CandidatosModel.conta_quantos_candidatos_existem_em_lista(consulta_candidatos_que_vao_compor_rs_ppi_cd)

                    CandidatosModel.inserir_convocados_nova_chamada(consulta_candidatos_que_vao_compor_rs_ppi_cd, numero_chamada)

                    if qtd_candidatos_que_vao_compor_rs_ppi_cd < vagas_rs_ppi_cd:
                        qtd_vagas_sobraram_rs_ppi_cd = vagas_rs_ppi_cd - qtd_candidatos_que_vao_compor_rs_ppi_cd

                        dic_rs_ppi_cd[curso.codigo_curso] = {
                            "codigo_curso": curso.codigo_curso,
                            "qtd_vagas_sobraram": qtd_vagas_sobraram_rs_ppi_cd
                        }

Method "inserir_convocados_nova_chamada:

# Atualizar candidato convocado em uma nova chamada
    @staticmethod
    def inserir_convocados_nova_chamada(lista_candidatos, numero_chamada):
        try:
            with Session() as session:

                for candidato in lista_candidatos:

                    candidato_a_ser_atualizado = session.query(CandidatosModel).filter_by(num_insc_enem=candidato.num_insc_enem).first()

                    candidato_a_ser_atualizado.chamada_aprovacao = 'chamada'+str(numero_chamada)

                session.commit()
                
                return True

        except Exception as e:

            # Em caso de exceção, imprima o erro e retorne False para indicar falha no cadastro
            print(f"Erro ao atualizar candidato convocado em nova chamada: {str(e)}")

            return False
Lucas
  • 1
  • 1
  • The `with` statement should close the session automatically. Do you have multiple threads running? Does your application log any errors? – snakecharmerb Aug 11 '23 at 14:03
  • 1
    @snakecharmerb Only error i got in terminal: sqlalchemy.exc.TimeoutError: QueuePool limit of size 5 overflow 10 reached, connection timed out, timeout 30.00 (Background on this error at: https://sqlalche.me/e/14/3o7r) – Lucas Aug 11 '23 at 14:12
  • Just going to add to @Lucas's answer. You can also see references to addressing the pool limit size here: https://stackoverflow.com/questions/24956894/sql-alchemy-queuepool-limit-overflow – Rex Charles Aug 11 '23 at 14:43
  • @RexCharles, I tried everything that is in https://stackoverflow.com/questions/24956894/sql-alchemy-queuepool-limit-overflow but not works. – Lucas Aug 11 '23 at 17:10
  • Your example code is ok, so we can only guess why the pool is overflowing, and the obvious guess is that somewhere you are not closing sessions properly and this is causing connections to stay checked out of the pool. If you don't believe that's the case you need to show us a [mre] that reproduces the behaviour. – snakecharmerb Aug 11 '23 at 18:05
  • @snakecharmerb I edited the post. I've included a little more information. See if that can help you help me. – Lucas Aug 11 '23 at 18:41
  • Still looks ok. It might be worth adding `echo_pool='debug'` to the `create_engine` call, so you can check the logs for connections which get checked out of the pool but do not get checked in afterwards. – snakecharmerb Aug 12 '23 at 18:18

0 Answers0