পাইথন স্ক্লাইট 3 এবং একত্রীকরণ


87

আমার কাছে পাইথন প্রোগ্রাম রয়েছে যা "থ্রেডিং" মডিউলটি ব্যবহার করে। প্রতি সেকেন্ডে একবার, আমার প্রোগ্রামটি একটি নতুন থ্রেড শুরু করে যা ওয়েব থেকে কিছু ডেটা নিয়ে আসে এবং এই ডেটাটি আমার হার্ড ড্রাইভে সঞ্চয় করে। এই ফলাফলগুলি সংরক্ষণ করার জন্য আমি স্ক্লাইট 3 ব্যবহার করতে চাই, তবে আমি এটি কাজ করতে পারি না। সমস্যাটি নিম্নলিখিত লাইনটি সম্পর্কে বলে মনে হচ্ছে:

conn = sqlite3.connect("mydatabase.db")
  • আমি যদি প্রতিটি থ্রেডের মধ্যে কোডের এই লাইনটি রাখি, তবে আমি একটি অপারেশনাল ইরর পেয়েছি যা আমাকে জানিয়েছে যে ডাটাবেস ফাইলটি লক করা আছে। আমি অনুমান করি এর অর্থ এই যে অন্য একটি থ্রেডে স্কাইলাইট 3 সংযোগের মাধ্যমে mydatedia.db খোলা আছে এবং এটি লক হয়ে গেছে।
  • আমি যদি এই প্রোগ্রামের কোডটি মূল প্রোগ্রামটিতে রেখেছি এবং প্রতিটি থ্রেডে সংযোগ বস্তু (সংযোগ) পাস করি তবে আমি একটি প্রোগ্রামিংইরার পেয়েছি যে থ্রেডে তৈরি এসকিউএলাইট অবজেক্টগুলি কেবল একই থ্রেডে ব্যবহার করা যেতে পারে।

পূর্বে আমি আমার সমস্ত ফলাফল CSV ফাইলগুলিতে সঞ্চয় করছিলাম এবং এই ফাইল-লক করার কোনও সমস্যা নেই। আশা করি স্ক্লাইট দিয়ে এটি সম্ভব হবে। কোন ধারনা?


4
আমি লক্ষ করতে চাই যে পাইথনের আরও সাম্প্রতিক সংস্করণগুলিতে sqlite3 এর নতুন সংস্করণ অন্তর্ভুক্ত রয়েছে যা এই সমস্যাটি সমাধান করবে।
রায়ান Fugger

@ রায়ানফুগার আপনি কি জানেন যে এটির প্রাথমিকতম সংস্করণটি কী? আমি ২.7
notbad.jpeg

@ রায়ানফুগার এএফাইক নেই এমন প্রাক-বিল্ট সংস্করণ নেই যেখানে এসকিউএলাইট 3 এর নতুন সংস্করণ রয়েছে যা এটি স্থির করে আছে। আপনি নিজের তৈরি করতে পারেন, যদিও।
শেজি

উত্তর:


44

আপনি ভোক্তা-উত্পাদক প্যাটার্ন ব্যবহার করতে পারেন। উদাহরণস্বরূপ আপনি থ্রেডগুলির মধ্যে ভাগ করা সারি তৈরি করতে পারেন। ওয়েব থেকে ডেটা আনার প্রথম থ্রেড ভাগ করা কাতারে এই ডেটাটিকে সজ্জিত করে। আর একটি থ্রেড যা ডেটাবেস সংযোগের মালিক সারি থেকে ডেটা প্রাপ্য এবং এটি ডাটাবেসে পাস করে।


8
এফডাব্লুআইডাব্লু: স্ক্লাইটের পরবর্তী সংস্করণগুলির দাবি যে আপনি সংযোগ এবং বস্তুগুলি থ্রেডে জুড়ে দিতে পারেন (কার্সার ব্যতীত), তবে আমি বাস্তবে অন্যথায় খুঁজে পেয়েছি।
রিচার্ড লেভাসিউর

এভজেনি লাজিন উপরে বর্ণিত একটি উদাহরণ এখানে
খনন করে

4
আপনার ডেটাবেসকে একটি ভাগ করা কাতারের আড়ালে লুকিয়ে রাখা এই প্রশ্নের সত্যই একটি খারাপ সমাধান কারণ সাধারণভাবে এসকিউএল এবং বিশেষত এসকিউএলাইট ইতিমধ্যে বিল্ট-ইন লকিং ব্যবস্থা রয়েছে যা সম্ভবত আপনি নিজের দ্বারা তৈরি করতে পারেন এমন কিছুর চেয়ে সম্ভবত আরও বেশি পরিশ্রুত।
শেজি

4
আপনাকে প্রশ্নটি পড়তে হবে, সেই মুহুর্তে কোনও অন্তর্নির্মিত লক করার ব্যবস্থা ছিল না। অনেক সমসাময়িক এমবেডেড ডাটাবেসগুলির পারফরম্যান্স কারণে (যেমন: লেভেলডিবি) এই ব্যবস্থার অভাব রয়েছে।
এভজেনি লাজিন

180

জনপ্রিয় বিশ্বাসের বিপক্ষে, sqlite3 এর নতুন সংস্করণে কি একাধিক থ্রেড সমর্থন অ্যাক্সেস।

এটি keyচ্ছিক কীওয়ার্ড আর্গুমেন্টের মাধ্যমে সক্ষম করা যেতে পারে check_same_thread:

sqlite.connect(":memory:", check_same_thread=False)

4
আমি অপ্রত্যাশিত ব্যতিক্রম এবং এমনকি পাইথন এই বিকল্পটির সাথে ক্র্যাশ হয়েছে (উইন্ডোজ 32-এ পাইথন ২.7)।
reclosedev

4
ডক্স অনুসারে , বহু-থ্রেড মোডে কোনও একক ডাটাবেস সংযোগ একাধিক থ্রেডে ব্যবহার করা যাবে না। একটি সিরিয়ালযুক্ত মোডও রয়েছে
কেসব্যাশ

4
কিছু মনে করবেন না, কেবল এটি সন্ধান করেছেন: http://sqlite.org/compile.html#threadsafe
মেডিওরোস

4
@ ফ্রয়েএকএমএনে, দুঃখিত, এটি অনেক দিন আগেও ছিল না: মেমরি: ডাটাবেস। এর পরে আমি একাধিক থ্রেডে স্ক্লাইট সংযোগটি ভাগ করে নিই।
reclosedev

4
@ ফ্রয়েএকএমএনে, বহু-থ্রেড অ্যাক্সেসে পাইথন প্রক্রিয়াটি কোর-ডাম্পিং সহ আমি এটির মুখোমুখি হয়েছি। আচরণটি অনুমানযোগ্য ছিল, এবং কোনও ব্যতিক্রম লগ করা হয়নি। আমি যদি সঠিকভাবে মনে রাখি তবে এটি পড়া এবং লেখার জন্যই সত্য true এটি এমনই এক জিনিস যা আমি দেখেছি আসলে অজগরটি দুর্ঘটনাকবলিত: ডি। আমি থ্রেডস্যাফ মোডে সংকলিত স্ক্লাইটের সাহায্যে এটি চেষ্টা করি নি, তবে সেই সময়টিতে সিস্টেমের ডিফল্ট স্ক্লাইটটি পুনরায় সংকলনের স্বাধীনতা আমার ছিল না। আমি সদৃশ কিছু কাজ শেষ পর্যন্ত কি এরিক প্রস্তাব এবং প্রতিবন্ধী থ্রেড সামঞ্জস্য
verboze

17

নিম্নলিখিতটি mail.python.org.pipermail.1239789 এ পাওয়া গেছে

আমি সমাধানটি পেয়েছি। আমি জানি না কেন পাইথন ডকুমেন্টেশনে এই বিকল্পটি সম্পর্কে একটি শব্দ নেই। সুতরাং আমাদের সংযোগ ফাংশনে একটি নতুন কীওয়ার্ড যুক্তি যুক্ত করতে হবে এবং আমরা এর থেকে বিভিন্ন থ্রেডে কার্সার তৈরি করতে সক্ষম হব। সুতরাং ব্যবহার করুন:

sqlite.connect(":memory:", check_same_thread = False)

আমার জন্য নিখুঁতভাবে কাজ করে। অবশ্যই এখন থেকে আমার ডিবিতে নিরাপদ মাল্টিথ্রেডিং অ্যাক্সেসের যত্ন নেওয়া দরকার। যাইহোক সহায়তার চেষ্টা করার জন্য সমস্ত ধন্যবাদ।


(জিআইএল-এর সাথে, ডিবিতে সত্য মাল্টথ্রিড্রেড অ্যাক্সেসের পথে এখনও তেমন কিছুই দেখা যায়নি)
এরিক অ্যারোনস্টি

সতর্কতা : পাইথন ডক্সের বিকল্পটি সম্পর্কে এই কথাটি বলা আছে check_same_thread: "একই সংযোগ রচনার ক্রিয়াকলাপের সাথে একাধিক থ্রেড ব্যবহার করার সময় ব্যবহারকারীর দ্বারা ডেটা দুর্নীতি এড়াতে সিরিয়ালাইজ করা উচিত" " সুতরাং হ্যাঁ, আপনি একাধিক থ্রেড সহ এসকিউএলাইট ব্যবহার করতে পারবেন যতক্ষণ না আপনার কোডটি নিশ্চিত করে যে কোনও একটি থ্রেড যে কোনও সময় ডাটাবেসে লিখতে পারে। যদি এটি না হয় তবে আপনি আপনার ডাটাবেসটিকে দূষিত করতে পারেন।
Ajedi32

14

মাল্টিপ্রসেসিংয়ে স্যুইচ করুন । এটি অনেক বেশি ভাল, স্কেলগুলি ভাল, একাধিক সিপিইউ ব্যবহার করে একাধিক কোর ব্যবহারের বাইরে যেতে পারে এবং ইন্টারফেসটি পাইথন থ্রেডিং মডিউলটি ব্যবহার করার মতো same

অথবা, আলীর পরামর্শ অনুসারে, কেবল এসকিউএলএলচেমির থ্রেড পুলিং প্রক্রিয়াটি ব্যবহার করুন । এটি আপনার জন্য সমস্ত কিছু স্বয়ংক্রিয়ভাবে পরিচালনা করবে এবং কেবলমাত্র কয়েকটিটির উদ্ধৃতি দেওয়ার জন্য অনেকগুলি অতিরিক্ত বৈশিষ্ট্য রয়েছে:

  1. এসকিউএলএলচেমিতে এসকিউএল, পোস্টগ্রিস, মাইএসকিউএল, ওরাকল, এমএস-এসকিউএল, ফায়ারবার্ড, ম্যাক্সডিবি, এমএস অ্যাকসেস, সিবাস এবং ইনফর্মিক্সের উপভাষা অন্তর্ভুক্ত রয়েছে; আইবিএম একটি ডিবি 2 ড্রাইভারও মুক্তি দিয়েছে। সুতরাং আপনি যদি এসকিউএলাইট থেকে দূরে সরে যাওয়ার সিদ্ধান্ত নেন তবে আপনাকে আপনার অ্যাপ্লিকেশনটি নতুন করে লিখতে হবে না।
  2. ইউনিট অফ ওয়ার্ক সিস্টেম, এসকিউএএলএলচেমির অবজেক্ট রিলেশনাল ম্যাপারের (ওআরএম) একটি কেন্দ্রীয় অংশ, সীমাবদ্ধ থাকা / সন্নিবেশ / আপডেট / মুছে ফেলা অপারেশনগুলিকে সারিগুলিতে সজ্জিত করে এবং সেগুলিকে এক ব্যাচে ফেলেছে। এটি সম্পাদন করার জন্য এটি সারিতে থাকা সমস্ত পরিবর্তিত আইটেমগুলির একটি টপোলজিকাল "নির্ভরতা সাজান" সম্পাদন করে যাতে বিদেশী মূল সীমাবদ্ধতাগুলিকে সম্মান জানানো হয় এবং নিরপেক্ষ বিবৃতিগুলি একসাথে গ্রুপ করা হয় যেখানে তাদের মাঝে মাঝে আরও বাচ্চা করা যায়। এটি ম্যাক্সিয়ামিয়াম দক্ষতা এবং লেনদেনের সুরক্ষা তৈরি করে এবং অচলাবস্থার সম্ভাবনা হ্রাস করে।

11

আপনি এই জন্য থ্রেড ব্যবহার করা উচিত নয়। এটি মোচড়ের জন্য একটি তুচ্ছ কাজ এবং এটি সম্ভবত আপনাকে আরও উল্লেখযোগ্যভাবে এগিয়ে নিয়ে যেতে পারে।

কেবল একটি থ্রেড ব্যবহার করুন এবং অনুরোধটি সম্পূর্ণ হওয়ার সাথে সাথে লেখার জন্য একটি ইভেন্ট ট্রিগার করা হয়েছে।

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

আপনি আপনার ডেটা দিয়ে যা করছেন তার উপর নির্ভর করে আপনি সম্পূর্ণ ফলাফলটি সম্পূর্ণ স্ক্লাইটে ফেলে দিতে পারেন, এটি রান্না এবং ডাম্প করতে পারেন, বা এটি পড়ার সময় রান্না করে শেষের দিকে ফেলে দিতে পারেন।

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


7

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

যুক্ত বোনাসের জন্য, / আপনি যখন উপলব্ধি / সিদ্ধান্ত নেন যে কোনও সমবর্তী অ্যাপ্লিকেশনটির জন্য স্ক্লাইট ব্যবহার করা বিপর্যয় হতে চলেছে, আপনাকে মাইএসকিউএল, বা পোস্টগ্রিস বা অন্য কিছু ব্যবহার করতে আপনার কোড পরিবর্তন করতে হবে না। আপনি শুধু উপর স্যুইচ করতে পারেন।


4
কেন এটি অফিসিয়াল ওয়েবসাইটে কোথাও পাইথন সংস্করণ নির্দিষ্ট করে না?
নাম প্রকাশ করুন

3

একাধিক থ্রেডে একই কার্সারটি একই ত্রুটিযুক্ত হিসাবে ব্যবহার না করে একই থ্রেডে একই কার্সারটি ব্যবহার করতে আপনাকে ডাটাবেসে প্রতিটি লেনদেনেরsession.close() পরে ব্যবহার করতে হবে ।



0

আমি এভজিনির উত্তরটি পছন্দ করি - আন্ত-থ্রেড যোগাযোগ বাস্তবায়নের সর্বোত্তম উপায় হ'ল ক্যুইস। সম্পূর্ণতার জন্য, এখানে আরও কিছু বিকল্প রয়েছে:

  • স্পাড থ্রেডগুলি ব্যবহার শেষ হলে ডিবি সংযোগটি বন্ধ করুন। এটি আপনার ঠিক করে দেবে OperationalError, তবে পারফরম্যান্স ওভারহেডের কারণে খোলার এবং বন্ধ করার মতো সংযোগগুলি সাধারণত একটি নো-না।
  • শিশুদের থ্রেড ব্যবহার করবেন না। যদি প্রতি-সেকেন্ডে একবারের কাজটি যথাযথভাবে হালকা ওজনের হয় তবে আপনি আনতে এবং সঞ্চয় করতে গিয়ে পালাতে পারেন, তারপরে সঠিক মুহুর্ত পর্যন্ত ঘুমানো। এটি অনাকাঙ্ক্ষিত যেহেতু আনতে এবং স্টোর অপারেশনগুলি> 1 সেকেন্ড নিতে পারে এবং আপনি একাধিক-থ্রেড পদ্ধতির সাথে আপনার থাকা মাল্টিপ্লেক্সযুক্ত সংস্থার সুবিধা হারাবেন।

0

আপনার প্রোগ্রামের জন্য আপনাকে একযোগে নকশা করা দরকার। এসকিউএলাইটের স্পষ্ট সীমাবদ্ধতা রয়েছে এবং আপনার এগুলি মান্য করা উচিত, FAQ দেখুন (নীচের প্রশ্নটিও) see


0

থেরাপি আমার প্রশ্নের সম্ভাব্য উত্তর বলে মনে হচ্ছে। এর হোম পৃষ্ঠাটি আমার সঠিক কাজটি বর্ণনা করে। (যদিও আমি এখনও কোডটি কতটা স্থিতিশীল তা নিশ্চিত নই।)


0

ডেটা অধ্যবসায়ের জন্য আমি y_seial পাইথন মডিউলটি একবার দেখে নেব: http://yserial.sourceforge.net

যা একক SQLite ডাটাবেসকে ঘিরে ডেডলক সমস্যাগুলি পরিচালনা করে। যদি সম্মতিতে চাহিদা ভারী হয়ে যায় তবে স্টোকাস্টিক সময়ের মধ্যে লোড ছড়িয়ে দিতে সহজেই অনেকগুলি ডাটাবেসের ক্লাস ফার্ম স্থাপন করতে পারেন।

আশা করি এটি আপনার প্রকল্পকে সহায়তা করে ... 10 মিনিটের মধ্যে এটি কার্যকর করার পক্ষে যথেষ্ট সহজ হওয়া উচিত।


0

উপরের উত্তরগুলির মধ্যে আমি কোনও মানদণ্ড খুঁজে পাইনি তাই আমি সমস্ত কিছু বেনমার্ক করার জন্য একটি পরীক্ষা লিখেছি।

আমি 3 টি পদ্ধতির চেষ্টা করেছি

  1. এসকিউএল ডাটাবেস থেকে ক্রমিকভাবে পড়া এবং লেখা
  2. একটি থ্রেডপুলএক্সেকিউটার ব্যবহার / পড়ার জন্য
  3. প্রসেসপুলএক্সেকিউটার ব্যবহার / পড়তে লিখতে

ফলাফল এবং বেঞ্চমার্ক থেকে গ্রহণগুলি নীচে রয়েছে

  1. সিকোয়েনশিয়াল রিড / সিক্যুয়ালাল লেখার কাজটি সবচেয়ে ভাল
  2. আপনার যদি সমান্তরালে প্রক্রিয়া করতে হয় তবে সমান্তরালভাবে পড়তে প্রসেসপুলএক্সেকিউটার ব্যবহার করুন
  3. থ্রেডপুলএক্সেকিউটার ব্যবহার করে বা প্রসেসপুলএক্সেকিউটার ব্যবহার করে কোনও লেখার কাজ করবেন না কারণ আপনি ডাটাবেস লক করা ত্রুটিগুলিতে চলে যাবেন এবং আপনাকে আবার খণ্ড সন্নিবেশ করানোর চেষ্টা করতে হবে

আমার এই উত্তরটিতে আপনি মাপদণ্ডের জন্য কোড এবং সম্পূর্ণ সমাধান সন্ধান করতে পারেন এখানে আশা করি সহায়তা করে!


-1

লক করা ডেটাবেসগুলির সাথে ত্রুটি পাওয়ার সম্ভবত কারণ হ'ল আপনাকে অবশ্যই ইস্যু করতে হবে

conn.commit()

একটি ডাটাবেস অপারেশন শেষ করার পরে। আপনি যদি তা না করেন তবে আপনার ডাটাবেসটি লিখিত-লক হয়ে যাবে এবং সেভাবেই থাকবে। অন্যান্য থ্রেডগুলি যে লেখার জন্য অপেক্ষা করছে তা সময়ের পরে শেষ হবে (ডিফল্টটি 5 সেকেন্ডে সেট করা আছে, তার বিশদগুলির জন্য http://docs.python.org/2/library/sqlite3.html#sqlite3.conected দেখুন ) ।

একটি সঠিক এবং সমবর্তী সন্নিবেশের একটি উদাহরণ হ'ল:

import threading, sqlite3
class InsertionThread(threading.Thread):

    def __init__(self, number):
        super(InsertionThread, self).__init__()
        self.number = number

    def run(self):
        conn = sqlite3.connect('yourdb.db', timeout=5)
        conn.execute('CREATE TABLE IF NOT EXISTS threadcount (threadnum, count);')
        conn.commit()

        for i in range(1000):
            conn.execute("INSERT INTO threadcount VALUES (?, ?);", (self.number, i))
            conn.commit()

# create as many of these as you wish
# but be careful to set the timeout value appropriately: thread switching in
# python takes some time
for i in range(2):
    t = InsertionThread(i)
    t.start()

আপনি যদি এসকিউএলাইট পছন্দ করেন বা এসকিউএল ডাটাবেসগুলির সাথে কাজ করে এমন অন্যান্য সরঞ্জাম রয়েছে বা এসএসকিউাইট ডিবি ফাইলগুলির সাথে সিএসভি ফাইলগুলি প্রতিস্থাপন করতে চান বা আন্তঃ প্ল্যাটফর্ম আইপিসির মতো বিরল কিছু করতে হবে তবে এসকিউএলাইট একটি দুর্দান্ত সরঞ্জাম এবং উদ্দেশ্যটির জন্য খুব উপযুক্ত fit যদি নিজেকে সঠিক মনে না হয় তবে কোনও আলাদা সমাধান ব্যবহার করার জন্য নিজেকে চাপ দিন না!

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