Skip to content

Self-reference fails with inheritance #190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sqlalchemy-bot opened this issue May 28, 2006 · 4 comments
Closed

Self-reference fails with inheritance #190

sqlalchemy-bot opened this issue May 28, 2006 · 4 comments
Labels
bug Something isn't working high priority
Milestone

Comments

@sqlalchemy-bot
Copy link
Collaborator

Migrated issue, originally created by Anonymous

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.

@sqlalchemy-bot
Copy link
Collaborator Author

Michael Bayer (@zzzeek) wrote:

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.

@sqlalchemy-bot
Copy link
Collaborator Author

Changes by Michael Bayer (@zzzeek):

  • added labels: high priority

@sqlalchemy-bot
Copy link
Collaborator Author

Michael Bayer (@zzzeek) wrote:

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.

@sqlalchemy-bot
Copy link
Collaborator Author

Changes by Michael Bayer (@zzzeek):

  • changed status to closed

@sqlalchemy-bot sqlalchemy-bot added high priority bug Something isn't working labels Nov 27, 2018
@sqlalchemy-bot sqlalchemy-bot added this to the 0.2.0 milestone Nov 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working high priority
Projects
None yet
Development

No branches or pull requests

1 participant