SQLAlchemy:基于其他属性初始化属性 [英] SQLAlchemy: Initializing attribute based on other attribute

查看:113
本文介绍了SQLAlchemy:基于其他属性初始化属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用SQLAlchemy进行Python项目.我有以下课程(我省略了一些与问题无关的方法):

class Cmd(Base):
    __tablename__ = "commands"
    dbid = Column(Integer, Sequence("commands_seq"), primary_key = True)
    cmd_id = Column(SmallInteger)
    instance_dbid =  Column(Integer, ForeignKey("instances.dbid"))
    type = Column(String(20))

    __mapper_args__ = {
    "polymorphic_on" : type,
    "polymorphic_identity" : "Cmd"
    }

    def __init__(self, cmd_id):
        self.cmd_id = cmd_id
        self.cmd_name = event_names[self.cmd_id]

如您所见,在初始化类的实例时,属性cmd_name是使用event_names列表从cmd_id属性创建的(也省略了,这是一个包含命令名称的简单列表).

我创建对象Cmd,添加会话,提交会话.关闭应用程序并再次启动它后,我尝试使用SQLAlchemy查询加载此Cmd.该对象已加载,但当然不会调用__init__且未设置cmd_name.

我想知道在获取带有查询的Cmd对象后是否有一些简单的方法来执行某些代码(self.cmd_name = event_names[self.cmd_id]).当然,我可以做一个特殊的方法,并始终在查询后启动它,但是我正在寻找更优雅,更自动的方法.

我已经阅读了文档,并找到了一些有关ORM事件侦听器的信息,但是对于这种简单情况而言,它们似乎太多了.我还发现了有关属性事件的文章,但它们仅与column_propertyrelationship一起使用.有什么简短,优雅的方法可以实现我想要的?

解决方案

您可以使用@reconstructor装饰器:

from sqlalchemy.orm import reconstructor
class Cmd(Base):
    __tablename__ = "commands"
    dbid = Column(Integer, Sequence("commands_seq"), primary_key = True)
    cmd_id = Column(SmallInteger)
    instance_dbid =  Column(Integer, ForeignKey("instances.dbid"))
    type = Column(String(20))

    __mapper_args__ = {
    "polymorphic_on" : type,
    "polymorphic_identity" : "Cmd"
    }

    def __init__(self, cmd_id):
        self.cmd_id = cmd_id
        self.cmd_name = event_names[self.cmd_id]

    @reconstructor
    def init_db_load(self):
        self.cmd_name = event_names[self.cmd_id]

请参阅构造函数和对象初始化"下的 doc . /p>

I'm working on a Python project using SQLAlchemy. I have following class (I have omitted some methods irrelevant to the question):

class Cmd(Base):
    __tablename__ = "commands"
    dbid = Column(Integer, Sequence("commands_seq"), primary_key = True)
    cmd_id = Column(SmallInteger)
    instance_dbid =  Column(Integer, ForeignKey("instances.dbid"))
    type = Column(String(20))

    __mapper_args__ = {
    "polymorphic_on" : type,
    "polymorphic_identity" : "Cmd"
    }

    def __init__(self, cmd_id):
        self.cmd_id = cmd_id
        self.cmd_name = event_names[self.cmd_id]

As you see, on initializing instance of the class the attribute cmd_name is created from cmd_id attribute using event_names list (also omitted, it's a simple list containing command names).

I create object Cmd, add it session, commit session. After closing application and launching it again I try to load this Cmd using SQLAlchemy query. The object is loaded, but of course __init__ is not called and cmd_name is not set.

I would like to know if there is some simple way of executing some code (self.cmd_name = event_names[self.cmd_id]) after getting Cmd object with query. Of course I could do a special method and always launch it after query, but I'm seeking more elegant, automatic way.

I've read the documentation and found some information about ORM Event listeners, but they seem to be too much for such simple case. I've also found piece about Attribute Events, but they work with column_property and relationship only. Is there any short, elegant way to achieve what I want?

解决方案

You can use the @reconstructor decorator:

from sqlalchemy.orm import reconstructor
class Cmd(Base):
    __tablename__ = "commands"
    dbid = Column(Integer, Sequence("commands_seq"), primary_key = True)
    cmd_id = Column(SmallInteger)
    instance_dbid =  Column(Integer, ForeignKey("instances.dbid"))
    type = Column(String(20))

    __mapper_args__ = {
    "polymorphic_on" : type,
    "polymorphic_identity" : "Cmd"
    }

    def __init__(self, cmd_id):
        self.cmd_id = cmd_id
        self.cmd_name = event_names[self.cmd_id]

    @reconstructor
    def init_db_load(self):
        self.cmd_name = event_names[self.cmd_id]

See this doc under "Constructors and Object Initialization".

这篇关于SQLAlchemy:基于其他属性初始化属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆