python类属性和sql炼金术关系

时间:2011-08-05 12:59:02

标签: python sqlalchemy

好的,我有两个问题:

我的第一个将由sqlalchemy相关。所以我被迫使用sqllite,我必须实现一些级联删除。现在我发现关系可以完成这项工作,但是这些应该在父表中正常声明。但由于一些设计决定,我不得不在孩子身上做这件事,所以我做的事情就像:

class Operation(Base):
    """
    The class used to log any action executed in Projects.
    """
    __tablename__ = 'OPERATIONS'

    id = Column(Integer, primary_key=True)
    parameters = Column(String)
    ..... rest of class here ....

class DataType(Base):

    __tablename__ = 'DATA_TYPES'
    id = Column(Integer, primary_key=True)
    gid = Column(String)
    ...more params...
    parent_operation = relationship(Operation, backref=backref("DATA_TYPES", 
                                                    order_by=id, 
                                                    cascade="all,delete"))
    ...rest of class...

现在这似乎有效,但我仍然不确定一些事情。

  • 首先,从这里开始,我可以用parent_operation做什么?我的意思是我看到级联有效但我没有使用parent_operation,除了实际的声明。

    • 其次,上述情况中的“DATA_TYPES”,它是backref中的第一个参数,是否需要是子表的名称,还是每个模型需要唯一?

    • 最后,在我的例子中,Operation和DataType类都在同一个模块中,所以我可以将Operation作为关系中的第一个参数传递。现在,如果不是这种情况,我会将它们放在单独的模块中,如果我仍然想要声明这种关系,我应该将'Operation'或'OPERATION'传递给关系(Classname或Tablename?)


现在我的第二个是更核心的Python,但由于它仍然与上面有一些联系,我会在这里添加它。所以我需要能够以动态方式添加类属性。基本上我需要添加一个像上面声明的关系。

class BaseClass(object)    

def __init__(self):
    my_class = self.__class__
    if not hasattr(my_class, self.__class__.__name__):
        reference = "my_class." + self.__class__.__name__ + "= relationship\
        ('DataType', backref=backref('" + self.__class__.__name__ + "', \
        cascade='all,delete'))"
        exec reference

为什么我需要这样做的原因很复杂,并且与一些设计决策有关(基本上我需要扩展这一个的每个类都有一个声明为'DataType'类的关系)。现在我知道使用exec语句并不是一个好习惯。那么有更好的方法来做到这一点吗?

此致 波格丹

1 个答案:

答案 0 :(得分:0)

对于第二部分或您的问题,请记住,您的类构造函数中的任何内容都不会被SqlAlchemy检测。在您的示例中,您可以简单地在其自己的类中声明关系(请注意,它不会从您的declarative_base类继承),然后在任何子类中继承它,如下所示:

class BaseDataType(object):
    parent_operation = relationship(Operation, backref="datatype")

class DataTypeA(Base, BaseDataType):
    id = Column(Integer, primary_key=True)

class DataTypeB(Base, BaseDataType):
    id = Column(Integer, primary_key=True)

SqlAlchemy文档提供了可能的示例:

http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#mixing-in-relationships