2014-03-06 166 views
1

我有以下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现在将是一个猫或取决于它是什么类型的狗的对象。动物表具有此信息。

感谢

回答

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" 
+0

感谢您的帮助。 我明白了所有的工作。我只是希望我能够做到这样的事情: a =动物(1) 所以我不必每次都想写一个“session.query ...”。 – user1474424

0

我真的不知道如何这个应用到你写什么,但我已经做了类似的事情。

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

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