Flask-SQLAlchemy更新整个对象

时间:2015-07-21 07:59:25

标签: python flask sqlalchemy

我想知道是否有更短的方式来更新整个对象,
假设我有一个对象“Package”声明如下:

class Package(db.Model):
    __searchable__ = ['name','version','maintainer','uploaders']
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(80))
    version = db.Column(db.String(15))
    architecture = db.Column(db.String(255))
    maintainer = db.Column(db.String(255))
    sha256 = db.Column(db.String(200))
    sha1 = db.Column(db.String(50))
    md5sum = db.Column(db.String(50))
    depends = relationship('Package',
                           secondary=package_to_package,
                           primaryjoin=id==package_to_package.c.left_package_id,
                           secondaryjoin=id==package_to_package.c.right_package_id,
                           backref='neededBy')
    recommends = relationship('Package',
                           secondary=package_recommended,
                           primaryjoin=id==package_recommended.c.left_package_id,
                           secondaryjoin=id==package_recommended.c.right_package_id,
                           backref='recommendedBy')
    lastUpdate = db.Column(db.DateTime)
    distributionId = db.Column(db.Integer,db.ForeignKey('distribution.id'))
    componentId = db.Column(db.Integer,db.ForeignKey('component.id'))
    status = db.Column(db.String(50))
    format = db.Column(db.String(25))
    uploaders = db.Column(db.String(255))
    def __init__(self,name):
        self.name = name
        self.lastUpdate = datetime.utcnow()

    def __repr__(self):
        return '<Package : %r Version : %r Maintainer : %r componentId : %d >' % (
            self.name,
            self.version,
            self.maintainer,
            self.componentId)

我有一个更新这些对象的芹菜任务, 我更新此对象的第一种方法是:

 if isinstance(package, Package):
                # Check if Distribution already Exists
                recordedPackage = Package.query.filter_by(name=package.name,
                                                            distributionId=package.distributionId,
                                                            componentId=package.componentId).first()
                app.logger.debug("Does it already Exists ?")
                if recordedPackage is None:
                    package.depends = packagesNeeded
                    db.session.add(package)
                elif isinstance(recordedPackage,Package) :
                    app.logger.info("updating %r"%(recordedPackage))
                    recordedPackage = package
                    db.session.commit()

这种方法不会更新任何内容,所以我必须这样做:

elif isinstance(recordedPackage,Package) :
                    app.logger.info("updating %r"%(recordedPackage))
                    recordedPackage.version = package.version
                    recordedPackage.depends = packagesNeeded
                    recordedPackage.maintainer = package.maintainer
                    recordedPackage.md5sum = package.md5sum
                    recordedPackage.sha1 = package.sha1
                    recordedPackage.sha256 = package.sha256
                    recordedPackage.lastUpdate = datetime.utcnow()
                    [...]
                    db.session.commit()

这样做真的很动态或干净 有没有办法更新整个对象(当然没有它的id)? 谢谢你的发烧友

2 个答案:

答案 0 :(得分:0)

使用update方法;我通常会创建一个字典以使其可读:

dct = {"version": package.version, ... , "lastUpdate":datetime.utcnow()}
recordedPackage.update(dct)
db.session.commit()

请注意,即使在add之后也需要提交,因此请考虑将commit语句移到if / elif条件之外。

答案 1 :(得分:0)

最后,我将dir方法与getattr / setattr一起使用 在GG_Python中提出的类中实现update方法 看起来像这样:

 def update(self,newPackage):
    newPackageAttributes = [a for a in dir(newPackage) if not a.startswith('__')]
    for key in newPackageAttributes:
        try:
            if getattr(self,key) != getattr(newPackage, key) \
                    and key != 'id'\
                    and key != 'name':
                if type(getattr(newPackage, key)) == str:
                    setattr(self,key,getattr(newPackage, key))
        except AttributeError:
            app.logger.debug("attribute not found, no pb")
    self.lastUpdate = datetime.utcnow()

这样我就不会更新InstanceState等等 我可以稍后添加一些支票(比如名字应该是相同的等等......)
在解析包的方法上给我这样的东西:

recordedPackage = Package.query.filter_by(name=package.name,
                                        distributionId=package.distributionId,
                                        componentId=package.componentId).first()
app.logger.debug("Does it already Exists ?")
if recordedPackage is None:
    package.depends = packagesNeeded
    db.session.add(package)
elif isinstance(recordedPackage,Package) :
    app.logger.info("updating %r"%(recordedPackage))
    recordedPackage.update(package)

db.session.commit()

感谢您的建议