Estamos utilizando la base declarativa SQLAlchemy y tengo un método para el que quiero aislar el nivel de transacción. Para explicar, hay dos procesos que escriben simultáneamente en la base de datos y debo hacer que ejecuten su lógica en una transacción. El nivel de aislamiento de transacción predeterminado es LECTURA COMPROMETIDA, pero necesito poder ejecutar un fragmento de código usando niveles de aislamiento SERIALIZABLES.¿Cómo configuro el nivel de aislamiento de transacción en SQLAlchemy para PostgreSQL?
¿Cómo se hace esto con SQLAlchemy? En este momento, básicamente tengo un método en nuestro modelo, que hereda de la base declarativa de SQLAlchemy, que esencialmente necesita ser invocado transaccionalmente.
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
from psycopg2.extensions import ISOLATION_LEVEL_READ_COMMITTED
from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE
class OurClass(SQLAlchemyBaseModel):
@classmethod
def set_isolation_level(cls, level=ISOLATION_LEVEL_SERIALIZABLE):
cls.get_engine().connect().connection.set_isolation_level(level)
@classmethod
def find_or_create(cls, **kwargs):
try:
return cls.query().filter_by(**kwargs).one()
except NoResultFound:
x = cls(**kwargs)
x.save()
return x
Estoy haciendo esto para invocar esta usando un nivel de aislamiento de transacción, pero no está haciendo lo que espero. El nivel de aislamiento aún se LEA COMPROMETIDO por lo que veo en los registros de postgres. ¿Alguien puede ayudarme a identificar lo que estoy haciendo mal?
estoy usando SQLAlchemy 0.5.5
class Foo(OurClass):
def insert_this(self, kwarg1=value1):
# I am trying to set the isolation level to SERIALIZABLE
try:
self.set_isolation_level()
with Session.begin():
self.find_or_create(kwarg1=value1)
except Exception: # if any exception is thrown...
print "I caught an expection."
print sys.exc_info()
finally:
# Make the isolation level back to READ COMMITTED
self.set_isolation_level(ISOLATION_LEVEL_READ_COMMITTED)
Parece que el argumento 'isolation_level' de' create_engine() 'solo afecta al administrador de conexión principal, por lo que obtiene ese nivel de aislamiento en todas y cada una de las conexiones. ¿Encontraste una forma compatible con la agrupación de conexiones para lograr esto por sesión/conexión? Tu pregunta original parecía que solo la querías en cierto método. – Russ