फ्लास्क- SQLalchemy एक पंक्ति की जानकारी को अपडेट करता है


121

मैं किसी पंक्ति की जानकारी को कैसे अपडेट कर सकता हूं?

उदाहरण के लिए, मैं उस पंक्ति के नाम कॉलम को बदलना चाहूंगा जिसमें आईडी 5 है।

जवाबों:


205

फ्लास्क-SQLAlchemy प्रलेखन में दिखाए गए ट्यूटोरियल का उपयोग करके किसी ऑब्जेक्ट को प्राप्त करें । एक बार आपके पास इकाई है जिसे आप बदलना चाहते हैं, इकाई को ही बदल दें। फिर, db.session.commit()

उदाहरण के लिए:

admin = User.query.filter_by(username='admin').first()
admin.email = 'my_new_email@example.com'
db.session.commit()

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

फ्लास्क- SQLAlchemy SQLAlchemy पर आधारित है, इसलिए SQLAlchemy डॉक्स को भी देखें।


2
धन्यवाद मार्क। एक बात और। मैंने इसे इस तरह से देखा है 'db.add (उपयोगकर्ता)' तो 'dv.session.commit ()'। दोनों काम क्यों करते हैं? और क्या अंतर है?
पोर्चोच्ची

11
यह SQLAlchemy में क्षणिक, अलग और संलग्न वस्तुओं के बीच के अंतर के साथ करना है (देखें sqlalchemy.org/docs/orm/session.html#what-does-the-session-do )। इसके अलावा, कुछ और जानकारी के लिए माइकल बेयर की टिप्पणी को मेलिंग सूची ( group.google.com/group/sqlalchemy/browse_thread/thread/… ) पर पढ़ें ।
मार्क हिल्ड्रेथ

1
यदि आप अभी भी वहाँ से पढ़ने के बाद मतभेदों पर भ्रमित हैं, तो एक और सवाल पूछने पर विचार करें।
मार्क हिल्ड्रेथ जुएल

यदि स्तंभ डेटा प्रकार json है, तो नीचे विधि का उपयोग करें। bashelton.com/2014/03/…
अराम

@ मार्खिल्ड्रेथ मैं क्षेत्र के लिए एक डेटाइम मूल्य को अपडेट नहीं कर सका, मुझे क्या करना चाहिए? स्तंभ uesd_at = db.Column(db.DateTime)मैं सिर्फ चलाया जाता है, obj.used_at = datetime.datetime.now() db.session.commit()लेकिन क्षेत्र के लिए सेट मान नहीं है।
3

96

updateSQLAlchemy में BaseQuery ऑब्जेक्ट पर एक विधि है , जिसे द्वारा लौटाया जाता है filter_by

admin = User.query.filter_by(username='admin').update(dict(email='my_new_email@example.com')))
db.session.commit()

updateइकाई बदलने पर उपयोग करने का लाभ तब आता है जब कई वस्तुओं को अद्यतन किया जाना है।

यदि आप add_userसभी को अनुमति देना चाहते हैं admin,

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

नोटिस जो filter_byएक तर्क का =विरोध करता है के रूप में खोजशब्द तर्क (केवल एक का उपयोग करें ) filterलेता है।


1
पहली क्वेरी में, परिणाम को नाम दिया गया है admin, जो भ्रामक हो सकता है क्योंकि परिणाम अपडेट की गई पंक्तियों की संख्या होगी। है ना?
विकास प्रसाद

और क्या कोई रास्ता है, जहां मैं Userक्वेरी द्वारा प्रभावित आइटम प्राप्त कर सकता हूं , न कि प्रभावित उपयोगकर्ताओं की संख्या?
विकास प्रसाद


18

यह काम नहीं करता है यदि आप मॉडल के अचार विशेषता को संशोधित करते हैं। अपडेट को ट्रिगर करने के लिए अचार वाली विशेषताओं को प्रतिस्थापित किया जाना चाहिए:

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}

1
ऐसे मामलों में सबसे अच्छा तरीका क्या है?
kampta

आपको इसे कॉपी dataऔर पुन: असाइन करना होगा।
एसएएस

@sas तुम्हारा क्या मतलब है?
मोर्ट ज़ार्ट

आपको अपडेट तंत्र को ट्रिगर करने के लिए डेटा प्रॉपर्टी को कॉपी और असाइन करना होगा। नीचे दिए गए उत्तर पर एक नजर डालें:user.data = data
sas

9

बस मान असाइन करना और उन्हें कमिट करना सभी डेटा प्रकारों के लिए काम करेगा लेकिन JSON और पिकल्ड विशेषताएँ। चूँकि मसालेदार प्रकार ऊपर बताया गया है, इसलिए मैं 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()

यह डेटा {"देश": "श्रीलंका"} के साथ 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 की नकल करने के दर्दनाक कार्य से गुजरने के बजाय एक नए अधिनायक (इसे ऊपर के रूप में एक नए चर पर असाइन नहीं करना), जिसे काम करना चाहिए था मुझे ऐसा करने का एक सरल तरीका मिला। सिस्टम को ध्वजांकित करने का एक तरीका है जो JSONs बदल गया है।

निम्नलिखित कार्य कोड है।

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()

इसने एकदम जादू की तरह काम किया। इस पद्धति के साथ एक और विधि प्रस्तावित है आशा है कि मैंने कुछ मदद की है।


2
db.session.merge(user)इस कोड को जोड़ने से मेरे लिए काम किया, FYI करें।
जेफ ब्लूमेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.