Bruno Brs
Bruno Brs

Reputation: 693

Unidrectional OneToOne relationship SqlAlchemy in Python

I'm trying to make a OneToOne relationship in SqlAlchemy, where the child's table ID is already the Foreign Key, but it is throwing me the error:

sqlalchemy.orm.exc.DetachedInstanceError: Instance <Vetor at 0x7fcc81307070> is not bound to a Session; attribute refresh operation cannot proceed

Below, the two models and the service..

class CUBE(types.UserDefinedType):
 def get_col_spec(self, **kw):
   return "CUBE"

class Vetor(db.Model):
   id = db.Column(db.Integer, primary_key=True)
   data = db.Column(db.DateTime(), default=db.func.now())
   vetor = db.Column(CUBE)
   sistema_origem_id = db.Column(db.Integer)
   
   def __init__(self, vetor, sistema_origem):
       self.vetor = vetor
       self.sistema_origem_id = sistema_origem
       
   def __repr__(self):
       return "<Vetor(id='%s', data='%s', vetor='%s', sistema_origem_id='%s')>" % (self.id, self.data, self.vetor, self.sistema_origem_id)

class FBinary(db.Model):
    id = db.Column(db.Integer, db.ForeignKey("vetor.id"), primary_key=True)
    binario = db.Column(db.LargeBinary)
    contenttype = db.Column(db.String())

    def __init__(self, id, binario, contenttype):
        self.id = id
        self.binario = binario
        self.contenttype = contenttype
    
    def __repr__(self):
        return "<FBinary(id='%s', binario='%s', contentype='%s')>" % (self.id, self.binario, self.contenttype)

The class that tries to commit both:

    ....code.....

    face = Vetor(vetor, 1 ) 
    db.session.add(face)

    binario = FBinary(id=face, binario=foto_bytes, contenttype='')
    db.session.add(binario)

    db.session.commit()

Upvotes: 0

Views: 124

Answers (1)

above_c_level
above_c_level

Reputation: 3949

I could not reproduce your error. That being said, a possible solution should be:

    face = Vetor(vetor, 1 ) 
    db.session.add(face)
    db.session.comit()  # Now your database has an entry in Table vetor with id 1

    binario = FBinary(id=face.id, binario=foto_bytes, contenttype='')  # reference the id from your face object.
    db.session.add(binario)
    db.session.commit()

I assumed that vetor is some kind of data and not a Vetor object (why would you try to save a Vetor object in the vetor table?).

Hope that helps. Please consider to provide a minimal reproducible example in your next question.

Upvotes: 1

Related Questions