pyairtable icon indicating copy to clipboard operation
pyairtable copied to clipboard

ORM LinkField: many-to-many relation modeling

Open larsakerson opened this issue 3 years ago • 3 comments

I'm having trouble modeling an Airtable base that includes linked fields between several tables. The issue appears to be that I can't reference the linked object model until that model is declared, but each model has links to other tables.

A simplified instance, for example:

class TableOne(orm.Model):
     table_two = orm.fields.Linkfield("Table two", TableTwo, lazy=False)
     table_three = orm.fields.Linkfield("Table two", TableThree, lazy=False)

class TableTwo(orm.Model):
     table_one = orm.fields.Linkfield("Table one", TableOne, lazy=False)
     table_three = orm.fields.Linkfield("Table three", TableThree, lazy=False)

class TableThree(orm.Model):
     table_one = orm.fields.Linkfield("Table two", TableTwo, lazy=False)
     table_three = orm.fields.Linkfield("Table three", TableThree, lazy=False)

In which case I receive the following error on line 2 of this snippet: NameError: name 'TableTwo' is not defined

Is there a better way to approach modeling this base?

larsakerson avatar Sep 07 '22 15:09 larsakerson

You are right. What I have seen done in cases like this (Django, flask) is to provide class name as a string and lazily resolve the class later.... need to think about this one.

gtalarico avatar Sep 07 '22 16:09 gtalarico

Actually something like this might work @aleafa: https://stackoverflow.com/questions/3270045/python-circular-references

class A:
    ... # all fields except the circular references


class B:
    ... # all fields except the circular references

# then define the circular references:
A.b = Linkfield(..., A)
B.a = Linkfield(..., A)

If this is a serious/large application you may want to look into how and mitigation for memory leaks in circular references.

gtalarico avatar Sep 07 '22 16:09 gtalarico

Thanks, @gtalarico. I had tried this, but it causes a KeyError in the Model from_record method when creating an instance. This error occurs even though the linked field is present in the record result from Airtable and the field name referenced in the model matches the Airtable field name.

Thanks for the reference re mitigating memory leaks. Definitely worth keeping in mind in situations like this.

larsakerson avatar Sep 07 '22 21:09 larsakerson

This was resolved in #277; see https://pyairtable.readthedocs.io/en/stable/orm.html#linked-records

mesozoic avatar Aug 08 '23 08:08 mesozoic