pony.orm.core.ERDiagramError: Inconsistent reverse attribute

1.7k Views Asked by At

I am getting this error when specifying my tables on Pony ORM.

  File "business.py", line 79, in <module>
    db.generate_mapping()
  File "<string>", line 2, in generate_mapping
  File "/home/ancinedev/.pyenv/versions/3.6.1/lib/python3.6/site-packages/pony/utils/utils.py", line 58, in cut_traceback
    return func(*args, **kwargs)
  File "/home/ancinedev/.pyenv/versions/3.6.1/lib/python3.6/site-packages/pony/orm/core.py", line 724, in generate_mapping
    entity._link_reverse_attrs_()
  File "/home/ancinedev/.pyenv/versions/3.6.1/lib/python3.6/site-packages/pony/orm/core.py", line 3511, in _link_reverse_attrs_
    throw(ERDiagramError, 'Inconsistent reverse attributes %s and %s' % (attr, attr2))
  File "/home/ancinedev/.pyenv/versions/3.6.1/lib/python3.6/site-packages/pony/utils/utils.py", line 96, in throw
    raise exc
pony.orm.core.ERDiagramError: Inconsistent reverse attributes Pais.pessoas and Pessoa.identificador

My Pessoa table has an attribute called CD_PAIS and this attribute is a reference to Pais table, where it is set as a Primary Key.

class Pais(db.Entity):
    _table_ = ['SAD', 'TA_PAIS']
    codigo = PrimaryKey(int, column="CD_PAIS")
    nome = Required(str, column="NM_PAIS")
    pessoas = Set(lambda: Pessoa, reverse="identificador")

class Pessoa(db.Entity):
    _table_ = ['SAD', 'TB_PESSOA']
    identificador = PrimaryKey(int, column="ID_PESSOA")
    nome = Required(str, column="NM_PESSOA")
    tipo_pessoa = Required(str, column="IN_TIPO_PESSOA")
    numero_registro = Optional(str, column="NR_REGISTRO")
    pais = Required(Pais, reverse="codigo")

I tried many documentations and ways but was not success on that.

Thanks everyone for your time.

2

There are 2 best solutions below

0
On

The problem with your code snippet is that you mistakenly point the reverse attribute to the primary key of another entity. First of all, the reverse attribute should be the relationship attribute of another entity, not its primary key. So for the pessoas attribute in Pais entity it should be the pais attribute in the Pessoa entity:

class Pais(db.Entity):
    _table_ = ['SAD', 'TA_PAIS']
    codigo = PrimaryKey(int, column="CD_PAIS")
    nome = Required(str, column="NM_PAIS")
    pessoas = Set(lambda: Pessoa, reverse="pais")

class Pessoa(db.Entity):
    _table_ = ['SAD', 'TB_PESSOA']
    identificador = PrimaryKey(int, column="ID_PESSOA")
    nome = Required(str, column="NM_PESSOA")
    tipo_pessoa = Required(str, column="IN_TIPO_PESSOA")
    numero_registro = Optional(str, column="NR_REGISTRO")
    pais = Required(Pais, reverse="pessoas")

But in this example specifying the reverse attribute is not necessary, because Pony can figure out the relationship attributes itself. The reverse need to be specified only if you have more that one relationship between entities and automatic relationship building is not possible.

If you remove the reverse from the entities declarations, it will work just fine:

class Pais(db.Entity):
    _table_ = ['SAD', 'TA_PAIS']
    codigo = PrimaryKey(int, column="CD_PAIS")
    nome = Required(str, column="NM_PAIS")
    pessoas = Set(lambda: Pessoa)

class Pessoa(db.Entity):
    _table_ = ['SAD', 'TB_PESSOA']
    identificador = PrimaryKey(int, column="ID_PESSOA")
    nome = Required(str, column="NM_PESSOA")
    tipo_pessoa = Required(str, column="IN_TIPO_PESSOA")
    numero_registro = Optional(str, column="NR_REGISTRO")
    pais = Required(Pais)

Here you can find more information about entity relationships: https://docs.ponyorm.com/relationships.html

Also you might want to use the online Entity-Relationship Diagram Editor https://editor.ponyorm.com/. It can help you with data modeling for your application.

0
On

The problem is when the SQL is generated.

File "/home/dev/.pyenv/versions/3.6.1/lib/python3.6/site-packages/pony/orm/dbapiprovider.py", line 55, in wrap_dbapi_exceptions
    except dbapi_module.DatabaseError as e: raise DatabaseError(e)
pony.orm.dbapiprovider.DatabaseError: ORA-00904: "TB_PESSOA"."PAIS": invalid identifier

SELECT "TB_PESSOA"."ID_PESSOA", "TB_PESSOA"."NM_PESSOA", "TB_PESSOA"."IN_TIPO_PESSOA", "TB_PESSOA"."NR_REGISTRO", "TB_PESSOA"."PAIS"
FROM "SAD"."TB_PESSOA" "TB_PESSOA"
WHERE 0 = 1

The PAIS does not exist in TB_PESSOA in fact, it is a field called CD_PAIS that is a foreign key into TA_PAIS.