- changed status to wontfix
Mapping multiple classes to a single table in a mapped inheritance hierarchy does not populate tables correctly
Issue #891
resolved
The following code:
from sqlalchemy import *
from sqlalchemy.orm import *
db = create_engine('sqlite:///sa.db')
db.echo = False # Try changing this to True and see what happens
metadata = MetaData(db)
class Task(object):
pass
class CustomTask(Task):
pass
class MyTask(CustomTask):
pass
task = Table('task', metadata,
Column('task_id', Integer, primary_key=True),
Column('type', String(64)),
)
custom_task = Table('task_custom', metadata,
Column('task_id', Integer, ForeignKey('task.task_id'), primary_key=True),
)
mapper(
Task, task,
polymorphic_on=task.c.type,
polymorphic_identity='Task',
select_table=custom_task.outerjoin(task),
)
mapper(
CustomTask, custom_task,
polymorphic_identity='CustomTask',
inherits=Task,
)
mapper(
MyTask, custom_task,
polymorphic_identity='MyTask',
inherits=CustomTask,
)
metadata.create_all()
Session = sessionmaker(autoflush=True, transactional=True)
Session.configure(bind=db)
session = Session()
task = Task()
rtask = CustomTask()
crtask = MyTask()
session.save_or_update(task)
session.save_or_update(rtask)
session.save_or_update(crtask)
session.commit()
session.flush()
for task in session.query(task):
print task
Produces this SQL:
BEGIN TRANSACTION;
CREATE TABLE task (
task_id INTEGER NOT NULL,
type VARCHAR(64),
PRIMARY KEY (task_id)
);
INSERT INTO "task" VALUES(1,'Task');
INSERT INTO "task" VALUES(2,'CustomTask');
CREATE TABLE task_custom (
task_id INTEGER NOT NULL,
PRIMARY KEY (task_id),
FOREIGN KEY(task_id) REFERENCES task (task_id)
);
INSERT INTO "task_custom" VALUES(2);
INSERT INTO "task_custom" VALUES(3);
COMMIT;
Note the dangling task_custom
row with task_id=3
.
Comments (2)
-
repo owner -
Account Deleted Ah, thank you.
The bit I was missing was the
task.join(custom_task)
. Apologies for the spurious ticket. - Log in to comment
the mapping for
MyTask
doesn't fit into any of the three available categories (single, joined, or concrete), and also the outerjoin onTask
is backwards. try it like this:output: