Python类属性与SQLAlchemy关系
好的,我有两个问题:
第一个问题和sqlalchemy有关。我被迫使用sqlite,并且需要实现一些级联删除。现在我发现使用关系可以解决这个问题,但这些关系通常应该在父表中声明。不过由于一些设计上的决定,我被迫在子表中做这个,所以我写了类似这样的代码:
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'给关系(类名还是表名?)
我的第二个问题更偏向于核心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 个回答
关于你问题的第二部分,记住,在你的类构造函数里写的任何东西都不会被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