Prevent related object persistence in sqlalchemy

Question:

Environment

  • Python 3.8.10
  • SQLAlchemy 1.3.22

Problem

I am having a problem related to the stated here, but couldn’t find a solution yet: How to prevent related object persistence in sqlalchemy?

I have two models with a one to many relationship:

class A:
   b = db.relationship("B", back_populates="a", cascade="all,delete")

class B:
   a_id = db.Column('A_ID', db.Integer, db.ForeignKey('A.ID'), nullable=False)

   a = db.relationship('A', back_populates="b")

The thing is that at a certain point, I need to modify a certain field of B. To do so, I need to access the object A related to the current B object to do some checks. But, as A is a class that uses translations and we need to have that in mind.

What translate does is overwrite the translatable fields of A in the current instance, without storing them in the database (we have the translations on a diferent table due to backwards compatibility). I need to do that translation to do the checks and get the correct value I should set to B. The problem is as follows:

 # some_service.py

   def get_by_id(a_id):
      a = A.get_by_id(a_id)
      if a:
          return translate(a)

 # file_y.py
   def get_value_to_update_b(a_id)
      a = some_service.get_by_id(a_id)

      # do some stuff without saving anything to A

 # file_x.py
   b = B.get_by_id(id) # At this point, b.a stores the original A object

   value = file_y.get_value_to_update_b(b.a_id) # After this executes, b.a points to the translated one, instead of the original, so when B is saved, the translated A is saved too.

   b.value = value 
   session.add(b)
   session.commit()

As you can see, the problem is that when I translate A to do the checks, the reference from B gets updated to A_translated, so when I save B, A is saved too with the translated values, which is incorrect.

I have already tried modifying the cascade attribute of the relationships (to None and merge), making a copy of the object A before translating and some other choices. And changing the whole translation process, although a possibility, it’s something I would rather have as the last option as this is something that urges us.

Is there anything else I could do to prevent A being saved when B is saved? If you have any question about the process, as I think it can be a little bit messy, I would gladly answer you. Thank you very much

Asked By: Giovanni Cabrera

||

Answers:

In the end I ended up with another approach. I couldn’t find a solution for the simultaneous storing of A and B, but I just made the checks different so the translation didn’t overwrite the original instance.

Answered By: Giovanni Cabrera
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.