SQLAlchemy:تعيينات الكائنات المفقودة بعد الالتزام؟

StackOverflow https://stackoverflow.com/questions/1033199

  •  06-07-2019
  •  | 
  •  

سؤال

لدي مشكلة بسيطة في SQLAlchemy.لدي نموذج واحد في الجدول، لنسميه Model1 هنا.أريد إضافة صف في هذا الجدول، والحصول على المفتاح الذي تمت زيادته تلقائيًا، حتى أتمكن من إنشاء نموذج آخر به، واستخدام هذا المفتاح.هذا ليس تصميمًا معيبًا لقاعدة البيانات (علاقة 1:1 وما إلى ذلك).أنا ببساطة بحاجة إلى هذا المفتاح في جدول آخر، لأنه يتم نقل الجدول الآخر إلى مضيف بعيد، وأحتاج إلى المفاتيح المطابقة حتى تفهم الخوادم بعضها البعض.لن يكون هناك أي مرجع محلي آخر بين هذين الجدولين، كما أنه ليس من الممكن إنشاء علاقات بسبب ذلك.

خذ بعين الاعتبار الكود التالي:

object1 = model.Model1(param)
DBSession.add(object1)

# if I do this, the line below fails with an UnboundExecutionError.
# and if I dont do this, object1.id won't be set yet
#transaction.commit()

object2 = model.AnotherModel(object1.id) #id holds the primary, autoincremented key

تمنيت ألا أضطر حتى إلى الالتزام "يدويًا".ما أود تحقيقه بشكل أساسي هو أن "Model1" ينمو باستمرار، مع زيادة المفتاح الأساسي لـ Model.id.يمثل AnotherModel دائمًا جزءًا صغيرًا فقط من Model1، والذي لم تتم معالجته بعد.بالطبع يمكنني إضافة علامة في "Model1"، وهو حقل منطقي في الجدول لتحديد العناصر التي تمت معالجتها بالفعل، لكنني كنت آمل ألا يكون ذلك ضروريًا.

كيف يمكنني تشغيل الكود أعلاه؟

تحية،

توم

هل كانت مفيدة؟

المحلول

شيئين:

  • هل يمكن أن توضح ما هو المتغير transaction ملزمة ل؟
  • بالضبط ما هو البيان الذي يثير خطأ UnboundExecutionError؟
  • الرجاء تقديم رسالة الاستثناء الكاملة، بما في ذلك تتبع المكدس.
  • الشيء "الطبيعي" الذي يجب فعله في هذه الحالة هو الاتصال DBSession.flush().هل حاولت ذلك؟

مثال:

object1 = Model1(param)
DBSession.add(object1)
DBSession.flush()
assert object1.id != None # flushing the session populates the id

object2 = AnotherModel(object1.id)

للحصول على شرح رائع لجلسة SA وما flush() لا، انظر استخدام الجلسة.

أساسًا، flush() يتسبب في أن تصبح المثيلات المعلقة مستمرة - مما يعني أنه يتم إدراج كائنات جديدة في جداول قاعدة البيانات. flush() يقوم أيضًا بتحديث الجداول بقيم المثيلات التي تتتبعها الجلسة والتي تحتوي على تغييرات.

commit() القضايا دائما flush() أولاً.

ضمن المعاملة، يمكنك التدفق عدة مرات.يؤدي كل تدفق () إلى تحديثات و/أو إدراجات في قاعدة البيانات.يمكن الالتزام بالمعاملة بأكملها أو التراجع عنها.

نصائح أخرى

وإذا كنت ترغب في الحصول على معرفات المفتاح الأساسي جديدة لتوليد دون أي شيء ترتكب، مجرد دعوة session.flush (). والتي تنبعث منها كل شيء في انتظار إلى قاعدة البيانات في المعاملة الحالية.

ولقد استعملت هذا فقط مع ForeignKeys، لذلك كنت في الحالة الثانية بدلا ستفعل model.AnotherModel (MODEL1 = object1)، وبعد ذلك فقط عمل (TM). لذلك أظن أن هذا قد يكون هناك مشكلة مع النماذج الخاصة بك، لذلك ربما كنت قد وظيفة لهم أيضا؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top