Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

245
Visualizações
Bloqueo de nivel de base de datos SQlalchemy

Me pregunto si es posible bloquear de alguna manera un par de tablas de la base de datos para escritura protegida o algo así, para evitar que otra aplicación las modifique cuando una transacción está en curso.

Ahora tengo algo como esto. Tablas A, B y C, con relaciones de uno a muchos entre ellas A->B y B->C. Esta función recibe datos de rabbitmq y actualiza A, B y/o C (generalmente solo C) o crea nuevas filas si faltan.

 Session=scoped_session(session_factory) try: foo = Session.query(A).filter(....).one() except NoResultFound: Session.remove() return try: bar = Session.query(B).filter(......).one() except NoResultFound: bar = B(field1=x, field2=y etc.) Session.add(bar) try: xyzzy = Session.query(C).filter(...).order_by(...).limit(1).one() except NoResultFound: xyzzy = C(.......) Session.add(xyzzy) foo.fieldn = var1 bar.fieldn = var2 xyzzy.fieldn = var3 etc. Session.commit() Session.remove()

Todo esto funciona bien. El problema es que tengo otro programa (una secuencia de comandos de Python completamente diferente) que realiza una limpieza a pedido. Básicamente elimina todo, desde A, B y C. Esto también funciona.

Mi primer programa falla inmediatamente después de eliminar esto:

 sqlalchemy.orm.exc.StaleDataError: UPDATE statement on table 'C' expected to update 1 row(s); 0 were matched.

Puedo detectar esta excepción y reaccionar en consecuencia, pero ¿debo hacerlo? Este problema se resolvería si pudiera en ambos programas reservar A, B y C en el nivel de la base de datos para un archivo corto. Todas estas transacciones son de corta duración. Entiendo por la documentación de sqlalchemy que una sesión también debe iniciar una transacción, pero aparentemente esto significa algo diferente a una transacción a nivel de base de datos.

Lo que parece suceder es que mi Session.query(C) encuentra una fila, pero antes de que el primer programa emita Session.commit(), el otro programa la eliminó.

Hace más de 20 años con las bases de datos de los 90 y CI siempre comenzaba una transacción con una TRANSACCIÓN DECLARA... RESERVANDO A, B, C PARA ESCRITURA PROTEGIDA; o algo así. ¿Se ha ido ahora y solo necesito capturar la excepción, o aún puedo beneficiarme del bloqueo en el nivel de la base de datos?

hannu

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Puede realizar un bloqueo explícito de PostgreSQL con el comando LOCK :

 LOCK A, B, C IN ACCESS EXCLUSIVE MODE;

Sin embargo, bloquear tres mesas es una forma muy dura de resolver el problema. Dado que tiene una relación de 1 m, puede considerar bloquear la fila en A en su lugar, al comienzo de cada transacción:

 SELECT * FROM A WHERE ... FOR UPDATE;

La forma de hacer esto en SQLAlchemy es:

 foo = Session.query(A).filter(....).with_for_update().one()
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda