简体   繁体   English

从超类实例化一个子类

[英]Instantiating a subclass from a superclass

I have the following python code that creates a polymorphic structure in a MySQL DB using SQLAlchemy. 我有以下使用SQLAlchemy在MySQL DB中创建多态结构的python代码。

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

I was wondering what the best way is to load it such that: 我想知道最好的方式是这样加载它:

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

c would now be a Cat or a Dog object depending on what type it is. 根据其类型,c现在将是Cat或Dog对象。 The Animal table has this information. 动物表具有此信息。

Thanks 谢谢

This is not how you query the database using sqlalchemy. 这不是使用sqlalchemy查询数据库的方式。 In order to get an Animal for specific key all you need to do is to perform: 为了获得特定密钥的动物,您需要做的是:

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,)

Please note that the model your provided is incomplete. 请注意,您提供的模型不完整。 The one below should be a complete working one: 下面的一个应该是一个完整的工作中的一个:

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"

I don't really know exactly how to apply this to what you wrote, but I have done something similar. 我真的不知道该如何将其应用于您编写的内容,但是我做了类似的事情。

You will want to create a factory function; 您将要创建一个工厂函数; this will probably be in your base class, though it could probably be separate. 尽管可能是单独的,但这可能在您的基类中。 in any case, it needs to be a static function, so if you include it in your class, declare it @staticmethod . 无论如何,它都必须是静态函数,因此,如果将其包含在类中,则将其声明为@staticmethod

Second, you can access the __subclasses__ method eg BaseClass.__subclasses__() to get a list of actual subclasses of BaseClass . 其次,您可以访问__subclasses__方法,例如BaseClass.__subclasses__()以获得BaseClass的实际子类列表。 In my case, I scanned the subclasses looking for one that had a specific class attribute and then called its init function. 在我的情况下,我扫描了子类以查找具有特定类属性的子类,然后将其称为init函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM