python - SqlAlchemy: Convert inherited type from one to another -
let's have 2 different types both on same database table (single table inheritance):
class employee(db.model): id = db.column(db.integer, primary_key = true) name = db.column(db.string, nullable = false) discriminator = db.column('type', string) __mapper_args__ = {'polymorphic_on': discriminator} class manager(employee): __mapper_args__ = {'polymorphic_identity': 'manager'} division = db.column(db.string, nullable = false) role = db.column(db.string, nullable = false) class worker(employee): __mapper_args__ = {'polymorphic_identity': 'worker'} title = db.column(db.string, nullable = false)
(yes, i'm using flask-sqlalchemy , not plain vanilla) how might go converting 1 declarative model another. is, if "worker" promoted "manager?" how do that? have write raw sql that?
sorry if has been asked before couldn't find googles. please note, contrived example.
it's kludgy, , causes warning, can brute-force modify discriminator column setting property:
john_smith = session.query(employee).filter_by(name='john smith').one() john_smith.discriminator = 'manager' session.commit()
this cause warning like,
sawarning: flushing object <worker @ 0xdeadbeef> incompatible polymorphic identity 'manager'; object may not refresh and/or load correctly mapper._validate_polymorphic_identity(mapper, state, dict_)
you can ignore that, long fix issues cause. safest thing close session (session.close()
) or expunge (session.expunge_all()
) after commit.
if must, can fix issues john's object alone expunging john session (session.expunge(john_smith)
). have careful that; remaining references john_smith
keep object, although thankfully detached session
, won't allowed them.
i tried other obvious options well. neither worked, both illustrative of sqlalchemy's session
object stores , how:
session.refresh(john_smith)
fails withinvalidrequesterror: not refresh instance '<worker @ 0xdeadbeef>'
that's because sqlalchemy queries database
worker
(notemployee
) , can't find 1 name of john smith, because database knows john got promoted due fancy new value intype
column.session.expire(john_smith)
succeeds fails update john new class, , subsequent access him result inobjectdeletederror: instance '<worker @ 0xdeadbeef>' has been deleted, or row otherwise not present.
sqlalchemy still thinks john
worker
, , tries query himworker
. that's because he's still persisted insession.identity_map
, looks this:{(saexample2.employee, (1,)): <saexample2.worker @ 0xdeadbeef>}
so there's john, listed explicitly
worker
object. whenexpunge()
john session, entry in dictionary gets purged. whenexpire()
him, of mapped properties marked stale, still exists in dictionary.
Comments
Post a Comment