从超类实例化子类

时间:2014-03-06 04:50:34

标签: python sqlalchemy

我有以下python代码,它使用SQLAlchemy在MySQL数据库中创建多态结构。

class Animal(Base):
    key = Column(Integer(), Sequence("My Counter" ,1 ,1), primary_key = True)
    name = Column(String())
    discriminator = Column('type',String())
    __mapper_args__ = {'polymorphic_on':discriminator}

    def __init__(self,key,name):
        self.key = key
        self.name = name

class Cat(Animal):
    __tablename__ = 'cat'
    __mapper_args__ = {'polymorphic_identity':'cat'}
    def walk():
        pass

class Dog(Animal):
    __tablename__ = 'dog'
    __mapper_args__ = {'polymorphic_identity':'dog'}

    def walk():
         pass

我想知道加载它的最佳方法是:

a = Animal(key=1)
c = a.create()

c现在可能是Cat或Dog对象,具体取决于它的类型。 Animal表有这个信息。

由于

2 个答案:

答案 0 :(得分:1)

这不是使用sqlalchemy查询数据库的方式。为了获得特定密钥的动物,您需要做的就是执行:

my_key = 1
a = session.query(Animal).get(my_key)
# sqlalchemy will figure out the type automatically and will return object of proper class 
assert type(a) in (Cat, Dog,)

请注意,您提供的模型不完整。下面的模型应该是完整的模型:

class Animal(Base):
    __tablename__ = 'animal'
    key = Column(Integer(), Sequence("My Counter" ,1 ,1), primary_key = True)
    name = Column(String())
    discriminator = Column('type',String())
    __mapper_args__ = { 'polymorphic_on':discriminator, }

    def __init__(self,key,name):
        self.key = key
        self.name = name

class Cat(Animal):
    __tablename__ = 'cat'
    __mapper_args__ = {'polymorphic_identity':'cat'}
    key = Column(Integer(), ForeignKey('animal.key'), primary_key = True)

    def walk(self):
        print "cat walking"

class Dog(Animal):
    __tablename__ = 'dog'
    __mapper_args__ = {'polymorphic_identity':'dog'}
    key = Column(Integer(), ForeignKey('animal.key'), primary_key = True)

    def walk(self):
        print "dog walking"

答案 1 :(得分:0)

我真的不知道如何将这个应用到你写的内容上,但我做了类似的事情。

您需要创建工厂功能;这可能会在你的基类中,尽管它可能是分开的。在任何情况下,它都需要是一个静态函数,所以如果你把它包含在你的类中,请声明它@staticmethod

其次,您可以访问__subclasses__方法,例如BaseClass.__subclasses__()获取BaseClass的实际子类列表。在我的例子中,我扫描了子类,寻找具有特定类属性的子类,然后调用它的init函数。