Flask-SQLalchemy 更新一行信息

发布于 2024-11-23 20:29:57 字数 47 浏览 3 评论 0原文

如何更新行的信息?

例如,我想更改 id 为 5 的行的名称列。

How can I update a row's information?

For example I'd like to alter the name column of the row that has the id 5.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

笔芯 2024-11-30 20:29:59

我一直在寻找比 @Ramesh 的答案(很好)但仍然充满活力的东西。这是一个将更新方法附加到 db.Model 对象的解决方案。

您传入一个字典,它只会更新您传入的列。

class SampleObject(db.Model):
  id = db.Column(db.BigInteger, primary_key=True)
  name = db.Column(db.String(128), nullable=False)
  notes = db.Column(db.Text, nullable=False)

  def update(self, update_dictionary: dict):
    for col_name in self.__table__.columns.keys():
      if col_name in update_dictionary:
        setattr(self, col_name, update_dictionary[col_name])

    db.session.add(self)
    db.session.commit()

然后在路线中您可以执行以下操作

object = SampleObject.query.where(SampleObject.id == id).first()
object.update(update_dictionary=request.get_json())

I was looking for something a little less intrusive then @Ramesh's answer (which was good) but still dynamic. Here is a solution attaching an update method to a db.Model object.

You pass in a dictionary and it will update only the columns that you pass in.

class SampleObject(db.Model):
  id = db.Column(db.BigInteger, primary_key=True)
  name = db.Column(db.String(128), nullable=False)
  notes = db.Column(db.Text, nullable=False)

  def update(self, update_dictionary: dict):
    for col_name in self.__table__.columns.keys():
      if col_name in update_dictionary:
        setattr(self, col_name, update_dictionary[col_name])

    db.session.add(self)
    db.session.commit()

Then in a route you can do

object = SampleObject.query.where(SampleObject.id == id).first()
object.update(update_dictionary=request.get_json())
江心雾 2024-11-30 20:29:59

更新烧瓶中的列

admin = User.query.filter_by(username='admin').first()
admin.email = '[email protected]'
admin.save()

Update the Columns in flask

admin = User.query.filter_by(username='admin').first()
admin.email = '[email protected]'
admin.save()
葬花如无物 2024-11-30 20:29:59

解决方案(会话)/在 Flask_sqlalchemy (db) 中:


db.session.query(BlogPost).where(BlogPost.id == post_id).
更新({
“attribute01”:新数据,
“attribute02”:新数据
})

db.session.commit()

Solution (session) / in Flask_sqlalchemy (db):


db.session.query(BlogPost).where(BlogPost.id == post_id).
update({
"attribute01": new_data,
"attribute02": new_data
})

db.session.commit()

梦里兽 2024-11-30 20:29:58

使用Flask-SQLAlchemy 文档中显示的教程检索对象。获得要更改的实体后,请更改实体本身。然后,db.session.commit()

例如:

admin = User.query.filter_by(username='admin').first()
admin.email = '[email protected]'
db.session.commit()

user = User.query.get(5)
user.name = 'New Name'
db.session.commit()

Flask-SQLAlchemy 基于 SQLAlchemy,因此请务必查看 SQLAlchemy 文档

Retrieve an object using the tutorial shown in the Flask-SQLAlchemy documentation. Once you have the entity that you want to change, change the entity itself. Then, db.session.commit().

For example:

admin = User.query.filter_by(username='admin').first()
admin.email = '[email protected]'
db.session.commit()

user = User.query.get(5)
user.name = 'New Name'
db.session.commit()

Flask-SQLAlchemy is based on SQLAlchemy, so be sure to check out the SQLAlchemy Docs as well.

筱武穆 2024-11-30 20:29:58

SQLAlchemy 中的 BaseQuery 对象有一个方法 update,该方法由 filter_by 返回。

num_rows_updated = User.query.filter_by(username='admin').update(dict(email='[email protected]')))
db.session.commit()

当有许多对象需要更新时,使用 update 相对于更改实体的优势就显现出来了。

如果您想向所有 admin 授予 add_user 权限,

rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()

请注意 filter_by 采用关键字参数(仅使用一个 =),而不是采用表达式的 filter

There is a method update on BaseQuery object in SQLAlchemy, which is returned by filter_by.

num_rows_updated = User.query.filter_by(username='admin').update(dict(email='[email protected]')))
db.session.commit()

The advantage of using update over changing the entity comes when there are many objects to be updated.

If you want to give add_user permission to all the admins,

rows_changed = User.query.filter_by(role='admin').update(dict(permission='add_user'))
db.session.commit()

Notice that filter_by takes keyword arguments (use only one =) as opposed to filter which takes an expression.

沉默的熊 2024-11-30 20:29:58

如果您修改模型的 pickled 属性,这将不起作用。应替换 Pickled 属性才能触发更新:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from pprint import pprint

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqllite:////tmp/users.db'
db = SQLAlchemy(app)


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)
    data = db.Column(db.PickleType())

    def __init__(self, name, data):
        self.name = name
        self.data = data

    def __repr__(self):
        return '<User %r>' % self.username

db.create_all()

# Create a user.
bob = User('Bob', {})
db.session.add(bob)
db.session.commit()

# Retrieve the row by its name.
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data)  # {}

# Modifying data is ignored.
bob.data['foo'] = 123
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data)  # {}

# Replacing data is respected.
bob.data = {'bar': 321}
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data)  # {'bar': 321}

# Modifying data is ignored.
bob.data['moo'] = 789
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data)  # {'bar': 321}

This does not work if you modify a pickled attribute of the model. Pickled attributes should be replaced in order to trigger updates:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from pprint import pprint

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqllite:////tmp/users.db'
db = SQLAlchemy(app)


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)
    data = db.Column(db.PickleType())

    def __init__(self, name, data):
        self.name = name
        self.data = data

    def __repr__(self):
        return '<User %r>' % self.username

db.create_all()

# Create a user.
bob = User('Bob', {})
db.session.add(bob)
db.session.commit()

# Retrieve the row by its name.
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data)  # {}

# Modifying data is ignored.
bob.data['foo'] = 123
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data)  # {}

# Replacing data is respected.
bob.data = {'bar': 321}
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data)  # {'bar': 321}

# Modifying data is ignored.
bob.data['moo'] = 789
db.session.commit()
bob = User.query.filter_by(name='Bob').first()
pprint(bob.data)  # {'bar': 321}
匿名的好友 2024-11-30 20:29:58

只需分配值并提交它们即可适用于除 JSON 和 Pickled 属性之外的所有数据类型。由于上面解释了 pickled 类型,因此我将记下一种略有不同但简单的更新 JSON 的方法。

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)
    data = db.Column(db.JSON)

def __init__(self, name, data):
    self.name = name
    self.data = data

假设模型如上所示。

user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()

这会将用户添加到带有数据 {"country":"Sri指定"} 的 MySQL 数据库中,

修改数据将被忽略。我的不起作用的代码如下。

user = User.query().filter(User.name=='Jon Dove')
data = user.data
data["province"] = "south"
user.data = data
db.session.merge(user)
db.session.flush()
db.session.commit()

我没有经历将 JSON 复制到新字典(而不是像上面那样将其分配给新变量)的痛苦工作,这本来应该有效,但我找到了一种简单的方法来做到这一点。有一种方法可以标记 JSON 已更改的系统。

以下是工作代码。

from sqlalchemy.orm.attributes import flag_modified
user = User.query().filter(User.name=='Jon Dove')
data = user.data
data["province"] = "south"
user.data = data
flag_modified(user, "data")
db.session.merge(user)
db.session.flush()
db.session.commit()

这就像一个魅力。
除了此方法之外,还提出了另一种方法此处
希望我对某人有所帮助。

Just assigning the value and committing them will work for all the data types but JSON and Pickled attributes. Since pickled type is explained above I'll note down a slightly different but easy way to update JSONs.

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)
    data = db.Column(db.JSON)

def __init__(self, name, data):
    self.name = name
    self.data = data

Let's say the model is like above.

user = User("Jon Dove", {"country":"Sri Lanka"})
db.session.add(user)
db.session.flush()
db.session.commit()

This will add the user into the MySQL database with data {"country":"Sri Lanka"}

Modifying data will be ignored. My code that didn't work is as follows.

user = User.query().filter(User.name=='Jon Dove')
data = user.data
data["province"] = "south"
user.data = data
db.session.merge(user)
db.session.flush()
db.session.commit()

Instead of going through the painful work of copying the JSON to a new dict (not assigning it to a new variable as above), which should have worked I found a simple way to do that. There is a way to flag the system that JSONs have changed.

Following is the working code.

from sqlalchemy.orm.attributes import flag_modified
user = User.query().filter(User.name=='Jon Dove')
data = user.data
data["province"] = "south"
user.data = data
flag_modified(user, "data")
db.session.merge(user)
db.session.flush()
db.session.commit()

This worked like a charm.
There is another method proposed along with this method here
Hope I've helped some one.

青瓷清茶倾城歌 2024-11-30 20:29:58

Models.py 定义序列化器

def default(o):
   if isinstance(o, (date, datetime)):
      return o.isoformat()

def get_model_columns(instance,exclude=[]):
    columns=instance.__table__.columns.keys()
    columns=list(set(columns)-set(exclude))
    return columns

class User(db.Model):
   __tablename__='user'
   id = db.Column(db.Integer, primary_key=True, autoincrement=True)
   .......
   ####

    def serializers(self):
       cols = get_model_columns(self)
       dict_val = {}
       for c in cols:
           dict_val[c] = getattr(self, c)
       return json.loads(json.dumps(dict_val,default=default))

,我们可以通过将 json 数据传递到更新查询中来动态更新记录:

class UpdateUserDetails(Resource):
   @auth_token_required
   def post(self):
      json_data = request.get_json()
      user_id = current_user.id
      try:
         instance = User.query.filter(User.id==user_id)
         data=instance.update(dict(json_data))
         db.session.commit()
         updateddata=instance.first()
         msg={"msg":"User details updated successfully","data":updateddata.serializers()}
         code=200
      except Exception as e:
         print(e)
         msg = {"msg": "Failed to update the userdetails! please contact your administartor."}
         code=500
      return msg

Models.py define the serializers

def default(o):
   if isinstance(o, (date, datetime)):
      return o.isoformat()

def get_model_columns(instance,exclude=[]):
    columns=instance.__table__.columns.keys()
    columns=list(set(columns)-set(exclude))
    return columns

class User(db.Model):
   __tablename__='user'
   id = db.Column(db.Integer, primary_key=True, autoincrement=True)
   .......
   ####

    def serializers(self):
       cols = get_model_columns(self)
       dict_val = {}
       for c in cols:
           dict_val[c] = getattr(self, c)
       return json.loads(json.dumps(dict_val,default=default))

In RestApi, We can update the record dynamically by passing the json data into update query:

class UpdateUserDetails(Resource):
   @auth_token_required
   def post(self):
      json_data = request.get_json()
      user_id = current_user.id
      try:
         instance = User.query.filter(User.id==user_id)
         data=instance.update(dict(json_data))
         db.session.commit()
         updateddata=instance.first()
         msg={"msg":"User details updated successfully","data":updateddata.serializers()}
         code=200
      except Exception as e:
         print(e)
         msg = {"msg": "Failed to update the userdetails! please contact your administartor."}
         code=500
      return msg
梦中楼上月下 2024-11-30 20:29:58

要使用 update 方法(更新会话外的主菜),您必须按如下步骤查询对象:

query = db.session.query(UserModel)
query = query.filter(UserModel.id == user_id)
query.update(user_dumped)
db.session.commit()

To use the update method (which updates the entree outside of the session) you have to query the object in steps like this:

query = db.session.query(UserModel)
query = query.filter(UserModel.id == user_id)
query.update(user_dumped)
db.session.commit()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文