سؤال

لدي بعض الكود الذي يلقي يسبب SyncDB لرمي خطأ (لأنه يحاول الوصول إلى النموذج قبل إنشاء الجداول).

هل هناك طريقة للحفاظ على الرمز من تشغيل SyncDB؟ شيء مثل:

if not syncdb:
    run_some_code()

شكرا :)

تعديل: PS - فكرت في استخدام إشارة post_init ... للرمز الذي يصل DB، هل هذه فكرة جيدة؟

مزيد من المعلومات

هنا مزيد من المعلومات حسب الطلب :)

لقد واجهت هذه المرات بضع مرة، على سبيل المثال ... كنت اختراقا على Django-Cron وقررتها ضرورية للتأكد من عدم وجود وظائف موجودة عند تحميل Django (لأنه يبحث في جميع التطبيقات المثبتة للوظائف ويضيف لهم على التحميل على أي حال).

لذلك أضفت الكود التالي إلى أعلى __init__.py ملف:

import sqlite3

try:
        # Delete all the old jobs from the database so they don't interfere with this instance of django
        oldJobs = models.Job.objects.all()
        for oldJob in oldJobs:
                oldJob.delete()
except sqlite3.OperationalError:
        # When you do syncdb for the first time, the table isn't 
        # there yet and throws a nasty error... until now
        pass

لأسباب واضحة هذا هو حماقة. لقد ربطت SQLite وأنا هناك أماكن أفضل لوضع هذا الرمز (هذا هو مجرد ما حدث عند المشكلة) لكنه يعمل.

كما ترى الخطأ الذي تحصل عليه هو الخطأ التشغيلي (في SQLite) ويقول تتبع المكدس شيئا على غرار "الجدول django_cron_job غير موجود"

المحلول

في النهاية، كان الهدف هو قم بتشغيل بعض الكود قبل تحميل أي صفحات.

يمكن تحقيق ذلك عن طريق تنفيذه في ملف URL.py، لأنه يجب استيراده قبل أن يتم تقديم صفحة (من الواضح).

وكنت قادرا على إزالة تلك المحاولة القبيحة / ما عدا كتلة :) الحمد لله (و S. Lott)

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

المحلول

"تحرير: PS - فكرت في استخدام إشارة Post_init ... للرمز الذي يصل إلى DB، هل هذه فكرة جيدة؟"

أبدا.

إذا كان لديك رمز يصل إلى النموذج قبل إنشاء الجداول، لديك مشاكل كبيرة كبيرة. ربما تفعل شيئا خطأ على محمل الجد.

عادة، تقوم بتشغيل SyncDB تقريبا مرة واحدة. يتم إنشاء قاعدة البيانات. ويستخدم تطبيق الويب الخاص بك قاعدة البيانات.

في بعض الأحيان، قمت بتغيير التصميم وإسقاط قاعدة البيانات وإعادة إنشاءها. ثم يستخدم تطبيق الويب الخاص بك قاعدة البيانات هذه لفترة طويلة.

أنت (عموما) لا تحتاج إلى رمز في __init__.py وحدة. يجب أن يكون لديك (تقريبا) أبدا رمز قابل للتنفيذ يقوم بعمل حقيقي في __init__.py وحدة. إنه أمر نادر جدا جدا وغير مناسب ل Django.

لست متأكدا من السبب في أن تعبث __init__.py متي جانجو كرون يقول أنك تجعل ترتيبات الجدولة الخاصة بك في urls.py.


يحرر

مسح السجلات هي شيء واحد.

العبث مع __init__.py و django-cron's base.py من الواضح أن طرق خاطئة تماما للقيام بذلك. إذا كان ذلك معقدا، فأنت تفعل ذلك خطأ.

من المستحيل معرفة ما تحاول القيام به، ولكن يجب أن يكون تافهة.

لك urls.py يمكن تشغيلها فقط بعد SyncDB وبعد تكوين جميع المواد Orm وتم تحويلها بشكل صحيح.

لك urls.py يمكن، على سبيل المثال، حذف بعض الصفوف ثم إضافة بعض الصفوف إلى جدول. في هذه المرحلة، تكون جميع مشكلات المزامنة خارج الطريق.

لماذا لا تملك المنطق الخاص بك urls.py?

نصائح أخرى

الرمز الذي يحاول الوصول إلى النماذج قبل أن يتم إنشاؤه يمكن أن يكون موجودا إلى حد كبير فقط على مستوى الوحدة النمطية؛ سيكون يجب تشغيل التعليمات البرمجية القابلة للتنفيذ عند استيراد الوحدة النمطية، كما يشير مثالك. هذا هو، كما كنت تخمن، وسبب syncdb فشل. يحاول استيراد الوحدة النمطية، ولكن فعل استيراد الوحدة يؤدي إلى تنفيذ رمز مستوى التطبيق؛ "التأثير الجانبي" إذا كنت سوف.

الرغبة في تجنب واردات الوحدة النمطية التي تسبب الآثار الجانبية قوية جدا في ثعبان if __name__ == '__main__': أصبحت اتفاقية البرامج النصية للنففاء القابلة للتنفيذ شائعة. عندما تقوم فقط بتحميل مكتبة التعليمات البرمجية، يؤدي تطبيق لبدء التنفيذ، والصداع الذي تتبعه :-)

بالنسبة لتطبيقات Django، يصبح هذا أكثر من صداع. النظر في تأثير وجود oldJob.delete() أعدم في كل مرة يتم استيراد الوحدة. قد يبدو الأمر كأنه ينفذ مرة واحدة فقط عند تشغيله مع خادم Django Development Server، ولكن في بيئة إنتاج، سيتم تنفيذها في كثير من الأحيان. إذا كنت تستخدم Apache، على سبيل المثال، فستطلق Apache في كثير من الأحيان العديد من عمليات الأطفال في انتظار التعامل مع الطلبات. كتقدم خادم طويل الأمد، سيحصل تطبيق Django على Boottrapped في كل مرة يتم فيها متوجها معالج لخادم الويب الخاص بك، مما يعني أن الوحدة ستستورد وحدة delete() سيتم استدعاء عدة مرات، وغالبا ما لا يمكن التنبؤ بها. لن تساعد الإشارة، لسوء الحظ، حيث يمكن إطلاق الإشارة في كل مرة تتم فيها تهيئة عملية Apache أيضا.

إنه ليس كذلك، راجع للشغل، مجرد خادم خادم قد يؤدي إلى تنفيذ التعليمات البرمجية الخاصة بك عن غير قصد. إذا كنت تستخدم أدوات مثل Epydoc، على سبيل المثال، فستقوم باستيراد التعليمات البرمجية الخاصة بك لتوليد وثائق API. هذا بدوره سيؤدي إلى بدء المنطق الخاص بك في تنفيذ التنفيذ، والذي من الواضح أنه تأثير جانبي غير مرغوب فيه فقط تشغيل محلل توثيق.

لهذا السبب، يتم التعامل مع كود التنظيف مثل هذا بشكل أفضل من خلال وظيفة كرون، والتي تبحث عن وظائف لا معنى لها على أساس دوري وتنظف DB. يمكن أيضا تشغيل هذا البرنامج النصي المخصص يدويا، أو بأي عملية (على سبيل المثال أثناء النشر، أو كجزء من اختبار الوحدة setUp() وظيفة لضمان تشغيل اختبار نظيف). بغض النظر عن كيفية القيام بذلك، فإن النقطة المهمة هي أن الكود مثل هذا يجب أن تنفذ دائما صراحة, ، بدلا من بشكل ضمني نتيجة لفتح الملف المصدر.

أتمنى أن يساعد ذلك. أعلم أنه لا تقدم وسيلة لتحديد ما إذا كان SyncDB قيد التشغيل، لكن مشكلة SyncDB ستتختفي بطريقة سحرية إذا قمت بتصميم تطبيق Django الخاص بك مع نشر الإنتاج في الاعتبار.

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