هل يمكنك إجراء استعلامات تشبه LINQ بلغة مثل Python أو Boo؟

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

سؤال

خذ هذا ببساطة سي# لينك الاستعلام، وتخيل ذلك db.Numbers هو SQL جدول بعمود واحد Number:

var result = 
    from n in db.Numbers
        where n.Number < 5
        select n.Number;

سيتم تشغيل هذا بكفاءة عالية في ج#, ، لأنه يولد SQL الاستعلام عن شيء من هذا القبيل

select Number from Numbers where Number < 5 

ما لا القيام به هو تحديد الجميع الأرقام من قاعدة البيانات، ثم قم بتصفيتها ج#, ، كما قد يبدو الأمر للوهلة الأولى.

بايثون يدعم بناء جملة مماثل:

result = [n.Number for n in Numbers if n.Number < 5]

لكنه if تقوم الجملة هنا بالتصفية من جانب العميل، بدلاً من جانب الخادم، وهو أقل كفاءة بكثير.

هل هناك شيء فعال مثل لينك في بايثون؟(أقوم حاليًا بالتقييم بايثون ضد. أيرون بايثون ضد. بوو, ، لذا فإن الإجابة التي تعمل بأي من هذه اللغات جيدة.)

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

المحلول

أعتقد أنه عند اكتمال IronPython 2.0، سيكون لديه دعم LINQ (انظر: هذا الموضوع لبعض الأمثلة المناقشة).الآن يجب أن تكون قادرًا على كتابة شيء مثل:

Queryable.Select(Queryable.Where(someInputSequence, somePredicate), someFuncThatReturnsTheSequenceElement) 

ربما كان هناك شيء أفضل قد وصل إلى IronPython 2.0b4 - هناك الكثير منه المناقشة الحالية حول كيفية التعامل مع تعارضات الأسماء.

نصائح أخرى

com.sqlsoup في sqlalchemy يمنحك الحل الأسرع في python على ما أعتقد إذا كنت تريد بطانة واحدة واضحة.انظر إلى الصفحة لترى.

يجب أن يكون شيء مثل ...

result = [n.Number for n in db.Numbers.filter(db.Numbers.Number < 5).all()]

LINQ هي إحدى ميزات لغة C# وVB.NET.وهو بناء جملة خاص يتعرف عليه المترجم ويعامل بشكل خاص.كما أنها تعتمد على ميزة لغة أخرى تسمى أشجار التعبير.

أشجار التعبير هي أ قليل مختلفة من حيث أنها ليست بناء جملة خاص.تتم كتابتها تمامًا مثل أي إنشاء مثيل لفئة أخرى، لكن المترجم يعاملها بشكل خاص تحت الأغطية عن طريق تحويل lambda إلى إنشاء مثيل لوقت التشغيل شجرة بناء الجملة مجردة.يمكن معالجتها في وقت التشغيل لإنتاج أمر بلغة أخرى (أي لغة أخرى).SQL).

يأخذ المترجمون C# وVB.NET بناء جملة LINQ، ويحولونه إلى lambdas، ثم يمررونه إلى إنشاءات شجرة التعبير.ثم هناك مجموعة من فئات الإطار التي تتعامل مع هذه الأشجار لإنتاج SQL.يمكنك أيضًا العثور على مكتبات أخرى، سواء من إنتاج MS أو من طرف ثالث، تقدم "موفري LINQ"، والتي تقوم أساسًا بإدخال معالج AST مختلف لإنتاج شيء ما من LINQ بخلاف SQL.

لذا فإن إحدى العوائق التي تحول دون القيام بهذه الأشياء بلغة أخرى هي السؤال عما إذا كانت تدعم بناء/معالجة AST في وقت التشغيل.لا أعرف ما إذا كانت أي تطبيقات لـ Python أو Boo تفعل ذلك، لكنني لم أسمع عن أي من هذه الميزات.

انظر عن كثب SQLAlchemy.ربما يمكن لهذا أن يفعل الكثير مما تريد.يمنحك بناء جملة Python لـ SQL القديم الذي يعمل على الخادم.

أحد العوامل الرئيسية لـ LINQ هو قدرة المترجم على إنشاء أشجار التعبير.أنا أستخدم ماكرو في Nemerle يقوم بتحويل تعبير Nemerle معين إلى كائن شجرة التعبير.يمكنني بعد ذلك تمرير هذا إلى طرق الامتداد Where/Select/etc على IQueryables.إنه ليس تمامًا بناء جملة C# وVB، لكنه قريب بدرجة كافية بالنسبة لي.

حصلت على الماكرو Nemerle عبر رابط في هذا المنشور:http://groups.google.com/group/nemerle-dev/browse_thread/thread/99b9dcfe204a578e

يجب أن يكون من الممكن إنشاء ماكرو مماثل لـ Boo.ومع ذلك، فهو يتطلب قدرًا كبيرًا من العمل، نظرًا للمجموعة الكبيرة من التعبيرات المحتملة التي تحتاج إلى دعمها.لقد أعطى Ayende دليلاً على المفهوم هنا:http://ayende.com/Blog/archive/2008/08/05/Ugly-Linq.aspx

يدعم Boo تعبيرات منشئ القائمة باستخدام نفس بناء جملة python.لمزيد من المعلومات حول ذلك، راجع وثائق Boo على تعبيرات المولد و قائمة الفهم.

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