এসকিউএলএলকেমি: ফ্লাশ () এবং কমিট () এর মধ্যে পার্থক্য কী?


422

এসকিউএলএলচেমির মধ্যে flush()এবং পার্থক্য কী commit()?

আমি ডকগুলি পড়েছি, তবে জ্ঞানী কেউ নয় - এগুলি মনে হয় এমন একটি পূর্ব-বোঝা যা আমার কাছে নেই।

আমি বিশেষত মেমরির ব্যবহারের ক্ষেত্রে তাদের প্রভাব সম্পর্কে আগ্রহী। আমি সিরিজ ফাইল (প্রায় 5 মিলিয়ন সারি) থেকে একটি ডাটাবেসে কিছু ডেটা লোড করছি এবং আমার সেশনটি মাঝে মাঝে পড়তে চলেছে - এটি একটি বিশাল ডাটাবেস এবং খুব বেশি স্মৃতিবিহীন একটি মেশিন।

আমি ভাবছি যদি আমি অনেক বেশি commit()এবং পর্যাপ্ত flush()কল না ব্যবহার করি - তবে পার্থক্যটি কী তা সত্যতা না বুঝেই বলা মুশকিল!

উত্তর:


533

একটি সেশন অবজেক্টটি মূলত একটি ডাটাবেসে পরিবর্তনের একটি চলমান লেনদেন (আপডেট, সন্নিবেশ, মোছা)। এই ক্রিয়াকলাপগুলি ডেটাবেসগুলিতে প্রতিশ্রুতিবদ্ধ না হওয়া অবধি স্থির থাকে না (যদি আপনার প্রোগ্রামটি মধ্য-সেশনের লেনদেনের কারণে কোনও কারণে বাতিল হয়ে যায় তবে এর মধ্যে কোনও আপত্তিহীন পরিবর্তনগুলি হারিয়ে যায়)।

সেশন অবজেক্টটি লেনদেনের ক্রিয়াকলাপগুলি নিবন্ধভুক্ত session.add()করে, তবে session.flush()ডাকা না হওয়া পর্যন্ত তাদের ডাটাবেসে যোগাযোগ করে না ।

session.flush()ডাটাবেসটিতে ক্রিয়াকলাপের একটি সিরিজ যোগাযোগ করে (সন্নিবেশ করুন, আপডেট করুন, মুছুন)। ডাটাবেস তাদের লেনদেনের অপেক্ষারত অপারেশন হিসাবে বজায় রাখে। পরিবর্তনগুলি স্থায়ীভাবে ডিস্কে স্থির থাকে না, বা অন্যান্য লেনদেনের জন্য দৃশ্যমান হয় যতক্ষণ না ডাটাবেসটি বর্তমান লেনদেনের জন্য একটি কমিটি না পেয়ে থাকে (যা তা session.commit()করে)।

session.commit() ডাটাবেসে সেই পরিবর্তনগুলি (চালিয়ে যায়) করে।

flush()হয় সবসময় একটি কল অংশ হিসাবে বলা commit()( 1 )।

আপনি যখন ডেটাবেসকে জিজ্ঞাসা করার জন্য একটি সেশন অবজেক্ট ব্যবহার করেন, তখন কোয়েরিটি ডাটাবেস এবং এটির অনির্ধারিত লেনদেনের ফ্লাশ অংশগুলি থেকে উভয়ই ফলাফল ফিরিয়ে দেবে। ডিফল্টরূপে, সেশনটি autoflushতাদের ক্রিয়াকলাপকে اعتراض করে তবে এটি অক্ষম করা যায়।

আশা করি এই উদাহরণটি আরও পরিষ্কার করে দেবে:

#---
s = Session()

s.add(Foo('A')) # The Foo('A') object has been added to the session.
                # It has not been committed to the database yet,
                #   but is returned as part of a query.
print 1, s.query(Foo).all()
s.commit()

#---
s2 = Session()
s2.autoflush = False

s2.add(Foo('B'))
print 2, s2.query(Foo).all() # The Foo('B') object is *not* returned
                             #   as part of this query because it hasn't
                             #   been flushed yet.
s2.flush()                   # Now, Foo('B') is in the same state as
                             #   Foo('A') was above.
print 3, s2.query(Foo).all() 
s2.rollback()                # Foo('B') has not been committed, and rolling
                             #   back the session's transaction removes it
                             #   from the session.
print 4, s2.query(Foo).all()

#---
Output:
1 [<Foo('A')>]
2 [<Foo('A')>]
3 [<Foo('A')>, <Foo('B')>]
4 [<Foo('A')>]

আরও একটি জিনিস: আপনি কি জানেন যে কলিং কমিট () ব্যবহার করা স্মৃতিশক্তি বাড়ায়, না কমিয়ে দেয় কি না?
এপি 257

2
এটি মাইসামের মতো লেনদেনকে সমর্থন করে না এমন ডিবি ইঞ্জিনগুলির ক্ষেত্রেও এটি মিথ্যা। যেহেতু কোনও চলমান লেনদেন নেই, ফ্লাশের কাছে কমিট থেকে নিজেকে আলাদা করার চেয়ে কম কিছু রয়েছে।
আন্ডারআরনে গেছে

1
@undrun সুতরাং আমি যদি এর session.query() পরেও করি তবে আমি কি session.flush()আমার পরিবর্তনগুলি দেখতে পাব? প্রদত্ত আমি মাইআইএসএএম ব্যবহার করছি।
হিমায়িত শিখা

1
এটি কি ভাল বা দুর্বল স্টাইলটি ব্যবহার করা উচিত flush()এবং বা আমি এটিকে commit()আলকেমির কাছে ছেড়ে দেওয়া উচিত। আমি flush()কিছু ক্ষেত্রে ব্যবহার করেছি কারণ পরবর্তী প্রশ্নের নতুন ডেটা বাছাই করা দরকার।
জেনস

1
@ জেনস ব্যবহার করুন autoflush( Trueডিফল্টরূপে) সমস্ত প্রশ্নের আগে এটি স্বয়ংক্রিয়ভাবে ফ্লাশ হয়ে যাবে, যাতে আপনাকে প্রতিবার মনে রাখতে হবে না।
কিরণ জোনালাগদদা

24

যেমন @ স্নাপশোই বলেছে

flush() আপনার এসকিউএল স্টেটমেন্টগুলি ডাটাবেসে প্রেরণ করে

commit() লেনদেন করে

কখন session.autocommit == False:

commit()flush()আপনি সেট করা হলে কল করবেautoflush == True

কখন session.autocommit == True:

আপনি কল করতে পারবেন না commit() যদি কোনও লেনদেন শুরু না করে থাকেন তবে আপনি (যা সম্ভবত আপনি এখনও করেন নি যেহেতু আপনি সম্ভবত কেবল লেনদেন পরিচালনা করার জন্য এই মোডটি ব্যবহার করবেন)।

এই মোডে, flush()আপনার ওআরএম পরিবর্তনগুলি সংরক্ষণ করতে আপনাকে অবশ্যই কল করতে হবে । ফ্লাশ কার্যকরভাবে আপনার ডেটাও কমিট করে।


24
"কমিট () আপনার অটোফ্লাশ == সত্য হলে ফ্লাশ () কল করবে" " সম্পূর্ণরূপে সঠিক নয়, বা কেবল বিভ্রান্তিকর। অটোফ্ল্যাশ সেটিংস নির্বিশেষে সর্বদা প্রতিশ্রুতিবদ্ধ us
ইলজা এভারিলä

3
autoflushPARAM কিনা তা নিয়ন্ত্রণ করে sqlalchemy প্রথমে একটি ফ্লাশ ইস্যু করবে যদি সেখানে একটি ক্যোয়ারী জারি এবং কমিট উপর অনিবার্য ফ্লাশ নিয়ন্ত্রণ সঙ্গে কিছুই করার আছে বিচারাধীন লিখেছেন আছে।
সুপারশুট

4

কমিট করতে পারলে ফ্লাশ কেন?

ডেটাবেস এবং স্কেলচেমির সাথে কাজ করার ক্ষেত্রে নতুন হিসাবে, পূর্ববর্তী উত্তরগুলি - যা flush()ডিবিতে এসকিউএল বিবৃতি প্রেরণ করে এবংcommit() রাখে - আমার কাছে পরিষ্কার ছিল না। সংজ্ঞাগুলি অর্থবোধ করে তবে আপনি কেবল প্রতিশ্রুতি না দেওয়ার পরিবর্তে কেন ফ্লাশ ব্যবহার করবেন তা সংজ্ঞাগুলি থেকে অবিলম্বে পরিষ্কার হয় না।

যেহেতু একটি প্রতিশ্রুতি সর্বদা ফ্লাশ হয় ( https://docs.sqlalchemy.org/en/13/orm/session_basics.html# কমিটিং ) এই শব্দগুলি সত্যই অনুরূপ। আমি মনে করি যে হাইলাইট করার জন্য বড় সমস্যাটি হ'ল ফ্লাশ স্থায়ী নয় এবং পূর্বাবস্থায় ফেরা যায়, যদিও একটি প্রতিশ্রুতি স্থায়ী হয়, এই অর্থে যে আপনি ডেটাবেসকে শেষ প্রতিশ্রুতিটি পূর্বাবস্থায় রাখতে বলতে পারবেন না (আমি মনে করি)

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

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

এটিতে আমার পোস্টটি এখানে দেখুন: স্কেলচেমিতে প্রতিশ্রুতিবদ্ধ করার সময় মুছে ফেলা বনাম কোনও আদেশ রয়েছে কি?

একইভাবে, কেউ জানেন কিনা অ্যাড অর্ডার রক্ষা করা হয় যখন সংগঠনের অর্থাৎ যদি আমি যোগ চেয়েছিলেন object1তারপর যোগ object2, নেই object1সামনে ডাটাবেসের সাথে যুক্ত হয়ে object2 অর্ডার সংরক্ষণ করেন SQLAlchemy যখন সেশনের বস্তু যোগ করার পদ্ধতি?

আবার, এখানে সম্ভবত সম্ভবত ফ্লাশ () ব্যবহার করা পছন্দসই আচরণটি নিশ্চিত করবে। সুতরাং সংক্ষিপ্তসার হিসাবে, ফ্লাশের জন্য একটি ব্যবহার হ'ল অর্ডার গ্যারান্টি সরবরাহ করা (আমার মনে হয়) আবার নিজেকে নিজেকে এমন একটি "পূর্বাবস্থায়িত করুন" বিকল্প দেয় যা প্রতিশ্রুতি দেয় না।

অটোফ্ল্যাশ এবং স্বতঃসংশোধন

দ্রষ্টব্য, অটোফ্ল্যাশ একটি আপডেট করা ডাটাবেসে ক্যোয়ারী অ্যাক্ট নিশ্চিত করার জন্য ব্যবহার করা যেতে পারে কারণ কোয়েরিটি কার্যকর করার আগে স্ক্লাচেমি ফ্লাশ হবে। https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.params.autoflush

অটোকোমিট এমন অন্য কিছু যা আমি পুরোপুরি বুঝতে পারি না তবে এটির ব্যবহারটি নিরুৎসাহিত করা বলে মনে হচ্ছে: https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.params। autocommit

স্মৃতি এর ব্যবহার

এখন আসল প্রশ্নটি আসলে স্মরণার্থের উদ্দেশ্যে প্রতিশ্রুতিবদ্ধ বনাম প্রতিশ্রুতির প্রভাব সম্পর্কে জানতে চেয়েছিল। যেমন অবিচল থাকার বা না রাখার ক্ষমতা ডাটাবেস অফার করে এমন কিছু (আমার মনে হয়), কেবলমাত্র ফ্লাশিং ডাটাবেসে অফলোড করার জন্য যথেষ্ট পরিমাণে হওয়া উচিত - যদিও প্রতিশ্রুতিতে আঘাত করা উচিত নয় (আসলে সম্ভবত সহায়তা করে - নীচে দেখুন) যদি আপনি পূর্বাবস্থায় ফিরে না যান তবে ।

স্ক্ল্যাচেমি ফ্ল্যাশ করা জিনিসগুলির জন্য দুর্বল রেফারেন্সিং ব্যবহার করে: https://docs.sqlalchemy.org/en/13/orm/session_state_management.html#session-references

এর অর্থ যদি আপনার কাছে কোনও তালিকা স্পষ্টভাবে অন্য কোথাও না ধরে থাকে, যেমন একটি তালিকা বা ডিকের মতো, স্ক্ল্যাচেমি এটিকে স্মরণে রাখবে না।

তবে, আপনার তখন চিন্তার মতো বিষয়গুলির ডাটাবেসের দিক রয়েছে। সম্ভবত প্রতিশ্রুতি না দিয়ে ফ্লাশিং লেনদেন বজায় রাখতে কিছু মেমরি জরিমানা নিয়ে আসে। আবার, আমি এটিতে নতুন তবে এখানে একটি লিঙ্ক যা ঠিক এটি প্রস্তাবিত বলে মনে হচ্ছে: https://stackoverflow.com/a/15305650/764365

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


1

এটি কঠোরভাবে আসল প্রশ্নের উত্তর দেয় না তবে কিছু লোক উল্লেখ করেছে যে আপনার সাথে session.autoflush = Trueব্যবহার করতে হবে না session.flush()... এবং এটি সর্বদা সত্য নয়।

আপনি যদি কোনও লেনদেনের মাঝামাঝি নতুন তৈরি করা অবজেক্টের আইডি ব্যবহার করতে চান তবে আপনাকে অবশ্যই কল করতে হবে session.flush()

# Given a model with at least this id
class AModel(Base):
   id = Column(Integer, primary_key=True)  # autoincrement by default on integer primary key

session.autoflush = True

a = AModel()
session.add(a)
a.id  # None
session.flush()
a.id  # autoincremented integer

এর কারণ এটি স্বয়ংক্রিয়ভাবে আইডিটি পূরণ autoflushকরে না (যদিও বস্তুর একটি ক্যোয়ারী, যা মাঝে মাঝে বিভ্রান্তির কারণ হতে পারে "কেন এটি এখানে কাজ করে তবে সেখানে না?" তবে স্নাপশো ইতিমধ্যে এই অংশটি covered েকে দিয়েছে )।


একটি সম্পর্কিত দিক যা আমার কাছে বেশ গুরুত্বপূর্ণ বলে মনে হচ্ছে এবং সত্যই উল্লেখ করা হয়নি:

কেন আপনি সব সময় প্রতিশ্রুতিবদ্ধ না? - উত্তরটি পারমাণবিকতা

বলার মতো অভিনব শব্দ: অপারেশনগুলির একটি টুকরোটি সফলভাবে সম্পাদন করতে হবে বা তাদের কোনওটি কার্যকর হবে না।

উদাহরণস্বরূপ, আপনি যদি কিছু অবজেক্ট (এ) তৈরি / আপডেট / মুছতে চান এবং তারপরে অন্যটি (বি) তৈরি / আপডেট / মুছে ফেলতে চান তবে (বি) ব্যর্থ হলে আপনি (এ) প্রত্যাবর্তন করতে চান। এর অর্থ এই 2 অপারেশনগুলি পারমাণবিক

সুতরাং, (বি) এর (এ) ফলাফলের প্রয়োজন হলে, আপনি flush(এ) commitপরে এবং (বি) পরে কল করতে চান ।

এছাড়াও, যদি session.autoflush is Trueআমি জিম্বোর জবাবের উপরে উল্লিখিত কেস বা অন্যদের বাদে , আপনাকে flushম্যানুয়ালি কল করার প্রয়োজন হবে না ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.