SQLAlchemy সারি এন্ট্রি কিভাবে আপডেট করবেন?


138

টেবিল ধরে তিন কলাম রয়েছে: username, passwordএবং no_of_logins

ব্যবহারকারী লগইন করার চেষ্টা করার সময়, এটি এর মতো একটি ক্যোয়ারী সহ একটি প্রবেশের জন্য পরীক্ষা করা হয়

user = User.query.filter_by(username=form.username.data).first()

পাসওয়ার্ড মেলে, তিনি আরও এগিয়ে। আমি কি করতে চান গণনা কতবার ব্যবহারকারী লগ ইন থাকলেও। সুতরাং যখনই তিনি সফলভাবে লগ আমি বাড়ায় চাই no_of_loginsক্ষেত্র নিজের গ্রামে ফিরে ব্যবহারকারী টেবিলে সংরক্ষণ করি। আমি নিশ্চিত নই যে কীভাবে SQLlchemy- র সাথে আপডেট ক্যোয়ারী চালানো যায়।

উত্তর:


132
user.no_of_logins += 1
session.commit()

12
stackoverflow.com/a/2334917/125507 বলে এটি এটি করার একটি খারাপ উপায়। এছাড়াও যদি সারিটি এখনও উপস্থিত না থাকে?
এন্ডোলিথ

6
এন্ডোলিথের লিঙ্ক অনুসারে, user.no_of_logins += 1জাতিগুলির অবস্থা তৈরি করতে পারে। পরিবর্তে ব্যবহার user.no_of_logins = user.no_of_logins + 1। SQL অনুবাদ করা পরেরটির সঠিক উপায় হয়ে: SET no_of_logins = no_of_logins + 1
চেইমজি

5
@ ছাইমজি আমি অনুমান করি আপনি বোঝাতে চেয়েছিলেন user.no_of_logins = User.no_of_logins + 1, বা অন্য কথায় একটি এসকিউএল এক্সপ্রেশন তৈরি করতে মডেলটির চালিত বৈশিষ্ট্যটি ব্যবহার করুন। এটি আপনার মন্তব্য হিসাবে একই জাতি শর্ত উত্পাদন করার 2 উপায় প্রদর্শন করে।
ইলজা এভারিলä

2
তারা না. প্রাক্তনটি একটি এসকিউএল এক্সপ্রেশনটির জন্য বৈশিষ্ট্যটি সেট করে, পরেরটি পাইথনে একটি স্থান-সংযোজন সম্পাদন করে এবং আবার রেসের সাথে পরিচয় করিয়ে দেয়।
ইলজা এভারিলি

1
@ জ্যারিজ্জো আমি সিরিয়ালিজেবল লেনদেনের বিচ্ছিন্নতা-স্তরের সাথে তেমন পরিচিত নই, তবে আমার বোঝার জন্য এটি পাইথনটিতে স্থান সংযোজন ব্যবহার করে যোগ করার অনুমতি দেবে। যদি কোনও প্রতিযোগিতা হয় তবে লেনদেনগুলির মধ্যে একটি সফল হবে এবং অন্যরা ব্যর্থ হবে এবং অবশ্যই পুনরায় চেষ্টা করতে হবে (ডিবির নতুন রাষ্ট্রের সাথে)। তবে আমি সিরিয়ালিজেবলকে ভুল বুঝেছি।
ইলজা এভারিলি

343

UPDATEব্যবহার করার বিভিন্ন উপায় রয়েছেsqlalchemy

1) user.no_of_logins += 1
   session.commit()

2) session.query().\
       filter(User.username == form.username.data).\
       update({"no_of_logins": (User.no_of_logins +1)})
   session.commit()

3) conn = engine.connect()
   stmt = User.update().\
       values(no_of_logins=(User.no_of_logins + 1)).\
       where(User.username == form.username.data)
   conn.execute(stmt)

4) setattr(user, 'no_of_logins', user.no_of_logins+1)
   session.commit()

3
আমি setattr(query_result, key, value)ফ্ল্যাস্ক এসকিউএলএলচেমিতে কিছু আপডেটের জন্য ব্যবহার করি তারপরে একটি প্রতিশ্রুতিবদ্ধ। এই প্যাটার্নটি ছাড় করার কোনও কারণ?
মার্ক

2
@ ডাটামাফিয়া: আপনি ব্যবহার করতে পারেন setattr(query_result, key, value)যা লেখার মতোই সমানquery_result.key = value
নিমা সুরেশ

Thx @ নিমাসোরেশ, আমি এটাই করি এবং হ্যাঁ সমতুল্য।
মার্ক

8
এই মামলার মধ্যে পার্থক্য ব্যাখ্যা করা সম্ভব? ধন্যবাদ!
হাটসেপসুট

1
@ হাটসেপসুট একটি পার্থক্য যা আমি আজ 41/2 এর মধ্যে এসেছি তা হ'ল: গ্রুপ. google.com/forum/#!topic/sqlalchemy/wGUuAy27otM
বিকাশ প্রসাদ

13

গৃহীত উত্তরের মন্তব্যে গুরুত্বপূর্ণ বিষয়টি স্পষ্ট করার উদাহরণ

আমি নিজেই এটির সাথে খেলা না হওয়া পর্যন্ত এটি বুঝতে পারি নি, তাই আমি বুঝতে পেরেছিলাম যে সেখানে আরও অনেকে বিভ্রান্ত হয়েছিল। বলুন আপনি যে ব্যবহারকারীর সাথে কাজ করছেন id == 6এবং no_of_logins == 30কখন আপনি কখন শুরু করবেন।

# 1 (bad)
user.no_of_logins += 1
# result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6

# 2 (bad)
user.no_of_logins = user.no_of_logins + 1
# result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6

# 3 (bad)
setattr(user, 'no_of_logins', user.no_of_logins + 1)
# result: UPDATE user SET no_of_logins = 31 WHERE user.id = 6

# 4 (ok)
user.no_of_logins = User.no_of_logins + 1
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6

# 5 (ok)
setattr(user, 'no_of_logins', User.no_of_logins + 1)
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6

বিন্দু

উদাহরণের পরিবর্তে ক্লাসটি উল্লেখ করে আপনি এসকিউএএলএলচেমিকে ইনক্রিমেন্টিং সম্পর্কে স্মার্ট হতে পারেন, এটি পাইথন সাইডের পরিবর্তে ডাটাবেস সাইডে ঘটবে। ডেটাবেসের মধ্যে এটি করা ভাল কারণ এটি ডেটা দুর্নীতিতে কম ঝুঁকিপূর্ণ (যেমন দুটি ক্লায়েন্ট একই সাথে দু'জনের পরিবর্তে কেবলমাত্র একটি ইনক্রিমেন্টের নেট ফলাফল সহ বৃদ্ধি করার চেষ্টা করে)। আমি ধরে নিয়েছি পাইথনে ইনক্রিমেন্টিং করা সম্ভব যদি আপনি তালা সেট করে থাকেন বা বিচ্ছিন্নতা স্তরটি গুছিয়ে দেন, তবে আপনাকে যদি তা না করতে হয় তবে কেন বিরক্ত করবেন?

একটি সতর্কীকরণ

আপনি যদি এসকিউএল জাতীয় কোড তৈরি করে এমন কোডের মাধ্যমে যদি দুবার বৃদ্ধি করতে যাচ্ছেন SET no_of_logins = no_of_logins + 1তবে আপনাকে কমেন্ট বা কমপক্ষে ইনক্রিমেন্টের মধ্যে ফ্লাশ করতে হবে, অন্যথায় আপনি কেবলমাত্র একটি ইনক্রিমেন্ট পাবেন:

# 6 (bad)
user.no_of_logins = User.no_of_logins + 1
user.no_of_logins = User.no_of_logins + 1
session.commit()
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6

# 7 (ok)
user.no_of_logins = User.no_of_logins + 1
session.flush()
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6
user.no_of_logins = User.no_of_logins + 1
session.commit()
# result: UPDATE user SET no_of_logins = no_of_logins + 1 WHERE user.id = 6

হ্যালো, আপনার উত্তরের জন্য ধন্যবাদ, কোনও int ভেরিয়েবলের পরিবর্তে আমি স্ট্রিং ভেরিয়েবল আপডেট করার চেষ্টা করছি, আমি কীভাবে এটি করব? আমি একটি স্ক্লাইট ডাটাবেস ব্যবহার করছি এবং যে পরিবর্তনগুলি আমি পরিবর্তন করতে চাই তা
বর্তমান_উজারে রয়েছে,

1
@ উদ্যানিবিল ডকুমেন্টেশন দেখুন, যা পুরোপুরি পুরোপুরি। টিউটোরিয়ালটির এই অংশটি স্ট্রিং ক্ষেত্রগুলি আপডেট করে: ডকস.সক্ল্যাচেমি.আর । অন্যথায়, আমি আপনাকে বিশেষভাবে কী আটকে রয়েছে তা দেখিয়ে একটি নতুন প্রশ্ন পোস্ট করার পরামর্শ দিচ্ছি।
মাররেডচিজ

লিঙ্কটির জন্য ধন্যবাদ, আমি সারা দিন অনুসন্ধানে কাটিয়ে দেওয়ার পরে, আমি জানি যে আমার সমস্যাটি db.session.commit () এর সাথে রয়েছে, এটি কনসোলে যে পরিবর্তনটি করা উচিত তা ঠিক ততটুকু ধরে রাখে না, অনুরূপ প্রশ্নগুলি পেয়েছি তবে জবাব দেওয়া হয়নি। আমার জন্য কাজ করুন, আসল ওয়েব অ্যাপে এটি আরও খারাপ! পরিবর্তনগুলি মোটেও রক্ষা পায় না, দীর্ঘ মন্তব্যের জন্য দুঃখিত তবে ওয়েবসাইটটির নীতিমালার কারণে আমি কোনও প্রশ্ন যুক্ত করতে পারছি না, কোনও সাহায্যই প্রশংসিত হবে।
দানি বিলেল

4

সাহায্যে user=User.query.filter_by(username=form.username.data).first()এ বক্তব্যে আপনি কি নির্দিষ্ট ব্যবহারকারীর পাবেন userপরিবর্তনশীল।

এখন আপনি নতুন অবজেক্ট ভেরিয়েবলের মান এর মত user.no_of_logins += 1পরিবর্তন করতে এবং sessionকমিট পদ্ধতিতে পরিবর্তনগুলি সংরক্ষণ করতে পারেন ।


2

আমি টেলিগ্রাম বট লিখেছিলাম, এবং আপডেট সারিগুলির সাথে কিছু সমস্যা আছে। এই উদাহরণটি ব্যবহার করুন, যদি আপনার কাছে মডেল থাকে

def update_state(chat_id, state):
    try:
        value = Users.query.filter(Users.chat_id == str(chat_id)).first()
        value.state = str(state)
        db.session.flush()
        db.session.commit()
        #db.session.close()
    except:
        print('Error in def update_state')

কেন ব্যবহার করবেন db.session.flush()? এজন্য >>> এসকিউএলএলকেমি: ফ্লাশ () এবং কমিট () এর মধ্যে পার্থক্য কী?


7
প্রতিশ্রুতি দেওয়ার ঠিক আগে ফ্লাশ সম্পূর্ণরূপে অপ্রয়োজনীয়। একটি প্রতিশ্রুতি সর্বদা স্পষ্টভাবে flushes। প্রশ্ন / এ-তে যতটুকু বলা হয়েছে যার সাথে আপনি লিঙ্ক করেছেন: " flush()সর্বদা কল করার অংশ হিসাবে ডাকা হয় commit()"
ইলজা এভারিলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.