好的,我有两个问题:
我的第一个将由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
语句并不是一个好习惯。那么有更好的方法来做到这一点吗?
此致 波格丹
答案 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