KarrLab / obj_tables

Tools for creating and reusing high-quality spreadsheets
https://objtables.org
MIT License
8 stars 2 forks source link

Error message: Add hint about defining all schema classes before instantiating them #161

Closed 0u812 closed 3 years ago

0u812 commented 3 years ago

This is a very nice project! Sorry if I should have filed an issue first, I thought this would be okay since it is a trivial change but you can let me know. Feel free to reject this PR if you have other plans for fixing this, I just wanted to prevent other people from struggling with tracing the root cause of this like I did.

Does this pull request add or fix a feature? [ ] Adds a feature [ X ] Fixes a feature

What feature does this pull request add or fix? I may have run into a trap for beginners where instantiating any schema class that is the recipient of a ManyTo*Attribute before defining all related schema classes raises a very hard to understand & hard to trace error. Consider the following code:

from obj_tables import (Model, TableFormat,
                        StringAttribute, ManyToOneAttribute)

class Company(Model):
    name = StringAttribute(unique=True, primary=True, verbose_name='Name')

    class Meta(Model.Meta):
        table_format = TableFormat.column
        attribute_order = ('name',)
        verbose_name = 'Company'
        verbose_name_plural = 'Companies'

# ERROR: this must come after the definition of Person!
google = Company(name='Google')

class Person(Model):
    name = StringAttribute(unique=True, primary=True, verbose_name='Name')
    company = ManyToOneAttribute(Company, related_name='employees', verbose_name='Company')

    class Meta(Model.Meta):
        table_format = TableFormat.row
        attribute_order = ('name', 'company')
        verbose_name = 'Person'
        verbose_name_plural = 'People'

pichai = Person(name='Sundar Pichai',
                company=google)

The google instance of Company needs to be created after defining Person or else you will see AttributeError: 'Company' object has no attribute 'employees'. This suggested change just adds a hint about what is going wrong:

AttributeError: 'Company' should have related name employees but it does not; did you remember to define all of your schema classes *before* instantiating them?

Is this request related to any issues? New issue.

Are there particular people or teams you would like to review this request? @jonrkarr @artgoldberg

jonrkarr commented 3 years ago

Thanks for the contribution