sqlalchemy inheritance, how to update polymorphic identity to default when changing attribute

Viewed 39

So I have the following models:

import sqlalchemy
from sqlalchemy import Column, String, Integer, create_engine, ForeignKey, Boolean, Text
from datetime import datetime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.orm.scoping import scoped_session
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy import event

Base = declarative_base()


class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    type = Column(String(50), default = "user")
    email = Column(String(64), unique=True, index=True)
    username = Column(String(64), unique=True, index=True)
    role_id = Column(Integer, ForeignKey('roles.id'))
    __mapper_args__ = {"polymorphic_on": type, "polymorphic_identity": "user"}
    
class Role(Base):
    __tablename__ = 'roles'
    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True)
    default = Column(Boolean, default = False, index = True)
    permissions = Column(Integer)
    users: sqlalchemy.orm.Query = relationship('User', backref='role', lazy="dynamic")

class AdminUser(User):
    role = Role(name="Administrator")
    __mapper_args__ = {
        "polymorphic_identity": "AdministratorUser",
    }

engine = create_engine('sqlite:///')
Base.metadata.create_all(engine)
session = scoped_session(sessionmaker(engine))

If I create an instance of an AdminUser:

user1 = AdminUser(email="admin@test.edu", username="test1")
session.add(user1)
session.commit()

Then administrator.role.name is indeed Administrator.

But if I want to change the role of user1 to some other role like this:

user1.role = Role(name = "someOtherRole")
session.add(user1)
session.commit()

It doesn't work, user1.role.name is still Administrator.

Using update like this also did not work session.query(AdminUser).filter_by(username = user1.username).update(dict(role = Role(name="someOtherRole")))

It threw an exception

"Role" object has no attribute '_bulk_update_tuples'

I realize this is because the type of user1 is still AdministratorUser. Is there a way to automatically update the type to that of the base class (i.e. user) if I change the role?

0 Answers
Related