- changed milestone to 0.9.xx
settable polymorphic identity
Issue #2792
new
this would need to be a new feature
# -*- coding: utf-8 -*-
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
DYNAMIC = True
#DYNAMIC = False
Base = declarative_base()
_rank_table = Table('rank', Base.metadata,
Column('id', Integer, primary_key=True),
Column('label', String)
)
_taxon_table = Table('taxon', Base.metadata,
Column('id', Integer, primary_key=True),
Column('refno', String),
Column('rank_id', Integer),
ForeignKeyConstraint(['rank_id']('rank_id'), ['rank.id']('rank.id'))
)
_taxon_relationship_table = Table('taxon_relationship', Base.metadata,
Column('taxon_id', Integer, primary_key=True),
Column('referenced_taxon_id', Integer, primary_key=True),
ForeignKeyConstraint(['taxon_id']('taxon_id'), ['taxon.id']('taxon.id')),
ForeignKeyConstraint(['referenced_taxon_id']('referenced_taxon_id'), ['taxon.id']('taxon.id')),
)
class Rank(Base):
__table__ = _rank_table
class Taxon(Base):
__table__ = _taxon_table
__mapper_args__ = {
'polymorphic_on': 'rank_id',
}
rank = relationship('Rank',
innerjoin=True,
backref=backref('taxa'))
class Family(Taxon):
if not DYNAMIC:
__mapper_args__ = {
'polymorphic_identity':-2147483640,
}
class Genus(Taxon):
if not DYNAMIC:
__mapper_args__ = {
'polymorphic_identity':-2147483636,
}
class Species(Taxon):
if not DYNAMIC:
__mapper_args__ = {
'polymorphic_identity':-2147483630,
}
class Subspecies(Taxon):
if not DYNAMIC:
__mapper_args__ = {
'polymorphic_identity':-2147483629,
}
class Variety(Taxon):
if not DYNAMIC:
__mapper_args__ = {
'polymorphic_identity':-2147483628,
}
# else:
# __mapper_args__ = {
# 'polymorphic_identity':"BOGUS",
# }
class Form(Taxon):
if not DYNAMIC:
__mapper_args__ = {
'polymorphic_identity':-2147483626,
}
class Cultivar(Taxon):
if not DYNAMIC:
__mapper_args__ = {
'polymorphic_identity':-2147483624,
}
class Group(Taxon):
if not DYNAMIC:
__mapper_args__ = {
'polymorphic_identity':-2147483623,
}
#else:
# __mapper_args__ = {
# 'polymorphic_identity':"BOGUS",
# }
class TaxonRelationship(Base):
__table__ = _taxon_relationship_table
taxon = relationship('Taxon',
innerjoin=True,
primaryjoin='Taxon.id==TaxonRelationship.taxon_id',
backref=backref('relationships',
cascade='all, delete-orphan',
passive_deletes=True))
referenced_taxon = relationship('Taxon',
innerjoin=True,
primaryjoin='Taxon.id==TaxonRelationship.referenced_taxon_id',
backref=backref('referenced_relationships'))
def _set_polymorphic_identity(subclass, identity):
# http://stackoverflow.com/questions/15112340/how-can-i-set-polymorphic-identity-after-a-class-is-defined
mapper = class_mapper(subclass)
if not DYNAMIC:
assert mapper.polymorphic_identity == identity
assert mapper.polymorphic_map is mapper.base_mapper.polymorphic_map
assert mapper.polymorphic_map[identity](identity) is mapper
else:
mapper.polymorphic_identity = identity
# ugly...
mapper.polymorphic_map[identity](identity) = mapper
# then very ugly.
mapper._identity_class = mapper.inherits._identity_class
def initialize_polymorphic_identity(session):
data = {"family": -2147483640,
"genus": -2147483636,
"species": -2147483630,
"subspecies": -2147483629,
"variety": -2147483628,
"form": -2147483626,
"cultivar": -2147483624,
"group": -2147483623}
session.add_all([ Rank(id=v, label=k) for k, v in data.items()
](
))
ranks = session.query(Rank).all()
def get_rank_id(label):
found_rank = None
for rank in ranks:
if rank.label == label:
found_rank = rank
break
if not found_rank:
raise Exception("No rank with label '" + label + "' has been found!")
return found_rank.id
def set_rank_identity(subclass, label):
_set_polymorphic_identity(subclass, get_rank_id(label))
set_rank_identity(Family, 'family')
set_rank_identity(Genus, 'genus')
set_rank_identity(Species, 'species')
set_rank_identity(Subspecies, 'subspecies')
set_rank_identity(Variety, 'variety')
set_rank_identity(Form, 'form')
set_rank_identity(Cultivar, 'cultivar')
set_rank_identity(Group, 'group')
# Initialization
engine = create_engine('postgresql://scott:tiger@localhost/test', echo=True)
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# Initialization polymorphic_identity
initialize_polymorphic_identity(session)
t1, t2 = Family(refno='t1'), Cultivar(refno='t2')
tr = TaxonRelationship(taxon=t1, referenced_taxon=t2)
session.add(tr)
session.commit()
t1.refno, t2.refno, tr.taxon_id
print "----------------"
print tr.referenced_taxon
Comments (5)
-
reporter -
reporter - changed milestone to 1.0.xx
-
reporter - edited description
- changed milestone to 1.1
-
reporter - changed milestone to 1.2
-
reporter - changed milestone to 1.3
- Log in to comment