En mi aplicación SQLAlchemy tengo el siguiente modelo:SQLAlchemy: campo único del modelo de volver a guardar después de tratar de ahorrar no único valor
from sqlalchemy import Column, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
from zope.sqlalchemy import ZopeTransactionExtension
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
class MyModel(declarative_base()):
# ...
label = Column(String(20), unique=True)
def save(self, force=False):
DBSession.add(self)
if force:
DBSession.flush()
Más adelante en el código para cada nuevo MyModel
objetos que desea generar label
al azar , y solo regenere si el valor generado ya existe en DB.
estoy tratando de hacer lo siguiente:
# my_model is an object of MyModel
while True:
my_model.label = generate_label()
try:
my_model.save(force=True)
except IntegrityError:
# label is not unique - will do one more iteration
# (*)
pass
else:
# my_model saved successfully - exit the loop
break
pero este error en caso de que generó por primera vez label
no es única y save()
llamados en el segundo (o posterior) de iteración:
InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (IntegrityError) column url_label is not unique...
cuando agrego DBSession.rollback()
en la posición (*) me sale esto:
ResourceClosedError: The transaction is closed
¿Qué debo hacer para manejar esta situación correctamente?
Gracias
Debe asignar el valor de retorno de 'declarative_base()' a una variable. De lo contrario, experimentará problemas al crear más de un modelo, ya que podría tener diferentes clases base para ellos. – ThiefMaster