Можете ли вы выполнять LINQ-подобные запросы на таких языках, как Python или Boo? - PullRequest
4 голосов
/ 23 сентября 2008

Возьмите этот простой C # LINQ запрос и представьте, что db.Numbers - это SQL таблица с одним столбцом Number:

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

Это будет очень эффективно работать в C # , потому что он генерирует SQL запрос, похожий на

select Number from Numbers where Number < 5 

Что он не делает, так это выбирает все числа из базы данных, а затем фильтрует их в C # , как это может показаться при первый.

Python поддерживает аналогичный синтаксис:

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

Но это предложение if здесь выполняет фильтрацию на стороне клиента, а не на стороне сервера, что гораздо менее эффективно.

Есть ли что-то столь же эффективное, как LINQ в Python ? (В настоящее время я оцениваю Python против IronPython против Boo , поэтому ответ, который работает на любом из этих языков, подойдет.)

Ответы [ 6 ]

6 голосов
/ 23 сентября 2008

sqlsoup в sqlalchemy дает вам самое быстрое решение в python, я думаю, если вам нужен чистый (ish) один вкладыш. Посмотрите на страницу, чтобы увидеть.

Это должно быть что-то вроде ...

result = [n.Number for n in db.Numbers.filter(db.Numbers.Number < 5).all()]
5 голосов
/ 23 сентября 2008

LINQ - это языковая особенность C # и VB.NET. Это специальный синтаксис, распознаваемый компилятором и обрабатываемый специально. Он также зависит от другой языковой функции, называемой деревьями выражений.

Деревья выражений немного отличаются тем, что они не являются специальным синтаксисом. Они написаны так же, как и любой другой экземпляр класса, но компилятор обрабатывает их специально под покровом, превращая лямбду в экземпляр дерева абстрактного синтаксиса времени выполнения . Во время выполнения ими можно манипулировать, чтобы создать команду на другом языке (например, SQL).

Компиляторы C # и VB.NET принимают синтаксис LINQ и превращают его в лямбды, а затем передают их в экземпляры дерева выражений. Кроме того, существует множество классов инфраструктуры, которые управляют этими деревьями для создания SQL. Вы также можете найти другие библиотеки, как MS, так и сторонних производителей, которые предлагают «провайдеров LINQ», которые в основном используют другой процессор AST для создания чего-то из LINQ, отличного от SQL.

Таким образом, одним из препятствий для выполнения этих действий на другом языке является вопрос, поддерживают ли они построение / манипулирование AST во время выполнения. Я не знаю, делают ли какие-либо реализации Python или Boo, но я не слышал о таких функциях.

5 голосов
/ 23 сентября 2008

Посмотрите внимательно на SQLAlchemy . Это, вероятно, может сделать многое из того, что вы хотите. Он дает вам синтаксис Python для простого старого SQL, который работает на сервере.

4 голосов
/ 23 сентября 2008

Я полагаю, что когда IronPython 2.0 будет завершен, у него будет поддержка LINQ (см. этот поток для некоторых примеров обсуждения). Прямо сейчас вы должны написать что-то вроде:

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

Что-то лучше могло бы превратиться в IronPython 2.0b4 - существует множество текущих дискуссий о том, как обрабатывались конфликты имен.

1 голос
/ 31 октября 2008

Boo поддерживает выражения генератора списков, используя тот же синтаксис, что и python. За дополнительной информацией обращайтесь к документации Boo по Выражениям генератора и Понимания списка .

1 голос
/ 25 октября 2008

Ключевым фактором для LINQ является способность компилятора генерировать деревья выражений. Я использую макрос в Nemerle, который преобразует данное выражение Nemerle в объект дерева выражений. Затем я могу передать это в методы расширения Where / Select / etc в IQueryables. Это не совсем синтаксис C # и VB, но это достаточно близко для меня.

Я получил макрос Nemerle по ссылке на это сообщение: http://groups.google.com/group/nemerle-dev/browse_thread/thread/99b9dcfe204a578e

Должно быть возможно создать подобный макрос для Boo. Однако это довольно сложная работа, учитывая большой набор возможных выражений, которые необходимо поддерживать. Айенде дала подтверждение концепции здесь: http://ayende.com/Blog/archive/2008/08/05/Ugly-Linq.aspx

...