স্কেলচেমি ফ্লাশ () এবং আইডি inোকানো হবে?


114

আমি এরকম কিছু করতে চাই:

f = Foo(bar='x')
session.add(f)
session.flush()

# do additional queries using f.id before commit()
print f.id # should be not None

session.commit()

কিন্তু f.idহয় Noneযখন আমি এটা চেষ্টা। আমি কীভাবে এটি কাজ করতে পারি?


2
আপনি কি এসএ ইঞ্জিনটি দিয়ে আরম্ভ করতে পারবেন echo=Trueএবং ফ্লাশ-টাইমে এসকিউএল কার্যকর করা হয় তা দেখুন? আপনি যে বর্ণনা করেছেন তাতে কাজ করা উচিত এবং আপনাকে আইডি দেওয়া উচিত, তবে এটির অন্য কোনও সমস্যা হতে পারে যার ফলস্বরূপ f.id কিছুই হয় না।
পাভেল রেপিন

উত্তর:


63

আপনার নমুনা কোডটি যেমন কাজ করা উচিত ছিল তেমন। এসকিউএলএলকেমি এটির একটি স্বয়ং-জেনারেটিং f.idপ্রাথমিক কী কলামটি ধরে ধরে একটি মান প্রদান করা উচিত । প্রাথমিক-কী বৈশিষ্ট্যগুলি flush()উত্পন্ন হওয়ার সাথে সাথেই প্রক্রিয়াটির মধ্যে অবিলম্বে পপুলেট হয় এবং কোনও কল করার commit()প্রয়োজন হয় না। সুতরাং এখানে উত্তর নীচের এক বা একাধিক মধ্যে থাকে:

  1. আপনার ম্যাপিংয়ের বিশদ
  2. যদি ব্যবহারের ব্যাক-এন্ডের কোনও বিজোড় quirks থাকে (যেমন, এসকিউএলাইট সম্মিলিত প্রাথমিক কীটির জন্য পূর্ণসংখ্যার মান উত্পন্ন করে না)
  3. যখন আপনি প্রতিধ্বনি চালু করবেন তখন নির্গত এসকিউএল কী বলে

1
আপনি সঠিক, শেলটিতে একটি দ্রুত চেক দেখায় এটি প্রাথমিক কী ক্ষেত্রটিকে একটি মান সহ পপুলেট করে। এটি কেন অনুশীলনে কাজ করছে না তা তদন্ত করতে হবে।
এলফ

3
"আপনার নমুনা কোডটি একটি মান সরবরাহ করা উচিত" এর মতো আপনি বলছেন যে "আপনি প্রথমে আইডির জন্য একটি মান দেওয়া উচিত ছিল", বরং "যে কোডটি আপনার ছিল তেমনভাবে কাজ করা উচিত ছিল" than আমার কাছে এটি স্পষ্ট হয়ে উঠল যে আপনি কেবল তৃতীয় পাঠের পরে পূর্বের চেয়ে আগেরটি বোঝাচ্ছেন। আপনি কি স্পষ্ট করতে পারেন?
স্টোকাস্টিক

126

আমি ঠিক একই সমস্যাটি চালিয়েছি এবং পরীক্ষার পরে আমি দেখতে পেয়েছি যে এই উত্তরগুলির মধ্যে কোনওটিই যথেষ্ট নয়।

বর্তমানে, বা স্কেলচেমি হিসাবে 6++ এর একটি খুব সহজ সমাধান রয়েছে (এটি আমি পূর্ববর্তী সংস্করণে উপস্থিত কিনা তা আমি জানি না, যদিও আমি এটি কল্পনা করি):

session.refresh ()

সুতরাং, আপনার কোডটি এর মতো দেখতে লাগবে:

f = Foo(bar=x)
session.add(f)
session.flush()
# At this point, the object f has been pushed to the DB, 
# and has been automatically assigned a unique primary key id

f.id
# is None

session.refresh(f)
# refresh updates given object in the session with its state in the DB
# (and can also only refresh certain attributes - search for documentation)

f.id
# is the automatically assigned primary key ID given in the database.

এটি কিভাবে করা যায়।


8
এটি এমন উত্তরের নিকটবর্তী হয়ে উঠছে যা আমার পক্ষে কাজ করতে পারে তবে আমি নিম্নলিখিত ত্রুটিটি পেয়েছি: अवैधঅনুষ্ঠানিক ত্রুটি: উদাহরণ '<....>' রিফ্রেশ করা যায়নি। এটি ফ্লাশের পরে উপস্থিত হয় যে দৃষ্টান্তটি কেবলমাত্র বিদ্যমান নেই। যে কোনও অন্তর্দৃষ্টি প্রশংসা করুন।
প্লেডফ্যান

1
তুমি সবে আমার পাছা বাঁচিয়েছ আমি মনে করি না আমি আর কখনও জাঙ্গো থেকে আগত ওআরএম ব্যবহার করব। ফ্লাশ () কমান্ড ডকুমেন্টেড আইএমএইচও হিসাবে কাজ করে না।
মার্ক

2
আপডেট, আমাকে ব্যবহার করতে হয়েছিল sessionmaker(autoflush=True), সেই কম্বো ডাব্লু / রিফ্রেশ () আমাকে সারি আইডি সরবরাহ করেছিল। #grrr
মার্ক

5
যদি আপনি আছে আত মধ্যে পার্থক্য বুঝতে পারেন flush()এবং commit(): এখানে একটি ভাল ব্যাখ্যা stackoverflow.com/a/4202016/1252290
Epoc

2
@ প্ল্যাডফ্যান পরিবর্তে flush()ব্যবহারের পরিবর্তে commit()এবং তার ঠিক পরে - এটিকে রিফ্রেশ করুন session.refresh(f), আমার জন্য কাজ করে এবং আমি এসকিউএএইচএলএলকেমি সংস্করণ ব্যবহার করি0.6.7
রিকি লেভি

20

সবার জন্য ধন্যবাদ। আমি কলাম ম্যাপিংটি সংশোধন করে আমার সমস্যার সমাধান করেছি। আমার জন্য, autoincrement=Trueপ্রয়োজন।

উত্স:

id = Column('ID', Integer, primary_key=True, nullable=False)

পরিবর্তিত পরে:

id = Column('ID', Integer, primary_key=True, autoincrement=True, nullable=True)

তারপর

session.flush()  
print(f.id)

ঠিক আছে!


6

dpb দ্বারা প্রদত্ত উত্তরের মত নয়, একটি রিফ্রেশ প্রয়োজনীয় নয়। একবার আপনি ফ্লাশ করার পরে, আপনি আইডি ক্ষেত্রটি অ্যাক্সেস করতে পারবেন, স্কেলচেমি স্বয়ংক্রিয়ভাবে আইডিটি রিফ্রেশ করে যা ব্যাকএন্ডে স্বয়ংক্রিয়ভাবে উত্পন্ন হয়

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


1
যেমন বলা হয়েছে কেবল রিফ্রেশ () আমার পক্ষে কাজ করেছিল। ডেটা মাইগ্রেশন করার সময় আমার কাছে এফকে জনপ্রিয় করার জন্য একটি লুপে সারি আইডি দরকার needed আমি প্রতিশ্রুতি, ফ্লাশ, সেশন হ্যাকিং এবং রিফ্রেশ () এর প্রতিটি কম্বো চেষ্টা করেছি যা কাজ করেছিল। আমার ডেটা অত্যন্ত পরিষ্কার এবং আমি সন্ধান করছি যে এসকিউএলএ খুব ভাল নয় (কমপক্ষে ৫ টি প্রধান ওআরএমএসে যথেষ্ট এক্সপ্রেস থাকা)। একটি অ্যাড () -> কমিট () / ফ্লাশ () এর জন্য সারি আইডি পাওয়ার চেষ্টা করে কেবল 5+ ঘন্টা মোড়ানো।
মার্ক

1

0কলিং session.addপদ্ধতির আগে আইডিতে নির্ধারিত হওয়াতে আমার একবার সমস্যা হয়েছিল । আইডিটি সঠিকভাবে ডেটাবেস দ্বারা নির্ধারিত হয়েছিল তবে পরবর্তী সেশন থেকে সঠিক আইডিটি উদ্ধার করা হয়নি session.flush()


-7

এর session.save_or_update(f)পরিবর্তে আপনার ব্যবহার করার চেষ্টা করা উচিত session.add(f)


1
save_or_update০.০ বা তার পর থেকে অবহেলা করা হয়েছে। session.add()এটা করা উচিত।
পাভেল রেপিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.