Self-reference fails with inheritance

Issue #190 resolved
Former user created an issue

The following program defines an inheritance relation between two tables. The base class also defines a self-reference. The program results in an error when executed.

import pkg_resources
pkg_resources.require("SQLAlchemy")
from sqlalchemy import *

metadata = BoundMetaData("postgres://robc@192.168.0.1:5432/sqlalchemy", echo='debug')

table1 = Table('table1', metadata,
               Column('id', Integer, primary_key=True),
               Column('related_id', Integer, ForeignKey('table1.id'), nullable=True),
               Column('type', String),
               )

table2 = Table('table2', metadata,
               Column('id', Integer, ForeignKey('table1.id'), primary_key=True),
               )

metadata.drop_all()
metadata.create_all()

join = polymorphic_union(
    {
    'table2' : table1.join(table2),
    'table1' : table1.select(table1.c.type=='table1'),
    }, None, 'pjoin')

class Table1(object):
    pass

class Table2(object):
    pass

table1_mapper = mapper(Table1, table1,
                       select_table=join,
                       polymorphic_on=join.c.type,
                       polymorphic_identity='table1',
                       properties={'next': relation(Table1, backref='prev', uselist=False, lazy=False)})

table2_mapper = mapper(Table2, table2,
                       inherits=table1_mapper,
                       polymorphic_identity='table2')

Results in the following error:

Traceback (most recent call last):
  File "bug.py", line 36, in ?
    properties={'next': relation(Table1, backref='prev', uselist=False, lazy=False)})
  File "/usr/lib/python2.4/site-packages/cairo/__init__.py", line 49, in mapper

  File "build/bdist.linux-i686/egg/sqlalchemy/orm/mapper.py", line 271, in __init__
  File "build/bdist.linux-i686/egg/sqlalchemy/orm/mapper.py", line 937, in init
  File "build/bdist.linux-i686/egg/sqlalchemy/orm/properties.py", line 242, in do_init
  File "build/bdist.linux-i686/egg/sqlalchemy/orm/properties.py", line 427, in do_init_subclass
  File "build/bdist.linux-i686/egg/sqlalchemy/orm/properties.py", line 329, in do_init_subclass
  File "build/bdist.linux-i686/egg/sqlalchemy/orm/mapper.py", line 848, in query
  File "build/bdist.linux-i686/egg/sqlalchemy/orm/query.py", line 28, in __init__
KeyError: <sqlalchemy.sql.Alias object at 0xa78a5cac>

It seems that the select_table and uselist=False don't go along.

Tested with SVN revision 1531.

Comments (3)

  1. Mike Bayer repo owner

    not surprising at all, self-referential and polymorphic loading are separately the wackiest functions SA has. i have not even attempted testing self-ref together with just plain inheritance yet. querying shouldnt be too hard to fix, its saving the stuff thats really going to be a pain. ill get around to this soon.

  2. Mike Bayer repo owner

    gonna mark it as fixed. changeset:1552 commits a pretty aggressive unit test for this, which is found here: browser:sqlalchemy/trunk/test/poly_linked_list.py, with most of the work being in changeset:1548, changeset:1550. Note that with the polymorphic union in use as well as the circular dependency, eager loading is off the table for now; even though the test says "lazy=False", those eager loads degrade to lazy loads when the queries are constructed (which also is something nice to test, that nothing breaks when eager loading is not possible).

    This test tests joined table and single table inheritance simultaneously among four different classes, as well as an extra one-to-many on some other random object, querying a forwards and backwards traversal over a linked list structure that is stored in an adjacency list table.

    You can still create queries that will load a wider range of nodes (i.e. more "eagerly") and feed them into the mapper in a manner similar to the "byroot_tree" example which is at browser:sqlalchemy/trunk/examples/adjacencytree/byroot_tree.py. I hope to add some extra features soon to make custom SQL queries easier to construct for mappers, including customized eager load criterion.

  3. Log in to comment