Node.js - преобразование SQL-запроса в Knex.js. - PullRequest
0 голосов
/ 08 января 2019

У меня есть SQL-запрос (Postgres), содержащий несколько join s, которые у меня возникают проблемы при преобразовании в один оператор Knex.js. Вот SQL-запрос:

SELECT 
    User.id, User.name, User.email,
    Role.name AS r_name,
    UserPofile.id AS p_id, UserPofile.date_of_birth AS p_dob,
    AuthToken.id AS at_id, AuthToken.token AS at_token, AuthToken.platform AS at_platform
FROM public."user" User
    LEFT JOIN public."user_role" UserRole ON User.id = UserRole.user_id
    LEFT JOIN public."role" Role ON UserRole.role_id = Role.id
    LEFT JOIN public."application" Application ON UserProfile.app_id = Application.id
    LEFT JOIN public."user_profile" UserProfile ON User.id = UserProfile.user_id
    LEFT JOIN public."auth_token" AuthToken ON User.id = AuthToken.user_id
WHERE 
    User.email LIKE 'some@email.com' AND
    Application.name LIKE 'awesome-application' AND
    AuthToken.platform LIKE 'mobile';

Вот мой код Knex.js:

    return knex('user').where({ email:'some@email.com' })
    .select([
        'user.id', 'user.name', 'user.email' // User
        'role.name AS rName' // Roles
        'user_profile.id AS pId', 'user_profile.date_of_birth AS pDob' // UserProfiles
        'auth_token.id AS atId' 'auth_token.platform AS atPlatform', 'auth_token.token AS atToken' // AuthTokens
    ])
    .leftJoin('user_profile', 'user_profile.user_id', 'user.id')
    .leftJoin('user_role', 'user_role.user_id', 'user.id')
    .leftJoin('role', 'role.id', 'user_role.role_id')
    .leftJoin('auth_token', 'auth_token.user_id', 'user.id')
    .then(users => {

        users = users.filter(user => { 
            return user.pApp_id === appId && user.atApp_id === appId && user.atPlatform === platform; 
        });
        return users;
    });

Это дает тот же результат, что и запрос SQL, но проблема в том, что мне нужно отфильтровать возвращенных пользователей в предложении .then() вызова Knex, потому что я не знаю, как добавить условия WHERE для Application.name и AuthToken.platform.

Вопрос:

Может кто-нибудь помочь мне разобраться, как структурировать предложение .where() моего кода Knex, чтобы оно было эквивалентно запросу SQL?

Примечания:

  • Я не знаю, как console.log SQL-запросы, которые производит Knex, поэтому я не совсем уверен, что мой текущий код Knex будет генерировать SQL-запрос над ним (за исключением правильного предложения WHERE). Однако я проверил, что он действительно возвращает те же результаты, запустив запрос в PgAdmin и console.log() с помощью users, возвращенного функцией Knex.
  • Я не включил миграции CREATE TABLE / Knex, которые определяли таблицы и столбцы, используемые в этом вопросе, потому что для меня это не было необходимым, и я не хочу задавать уже длинный вопрос еще дольше , Но если вам нужно это увидеть, пожалуйста, не стесняйтесь, дайте мне знать. Я с удовольствием включу это.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Для отладки вы можете использовать .toSQL() для отладки ваших запросов knex Документация .
Также хороший шпаргалка

В качестве решения для оперативного исправления вы можете использовать .raw() и вставить туда свой код SQL.

О WHERE условиях, вы можете просто связать их в конце вашего запроса knex.
Примерно так:

return knex('user')
  .select('user.id', 'user.name', 'user.email', 
    'role.name AS rName'
    'user_profile.id AS pId', 'user_profile.date_of_birth AS pDob', 
    'auth_token.id AS atId' 'auth_token.platform AS atPlatform', 'auth_token.token AS atToken'
   )
  .leftJoin('user_profile', 'user_profile.user_id', 'user.id')
  .leftJoin('user_role', 'user_role.user_id', 'user.id')
  .leftJoin('role', 'role.id', 'user_role.role_id')
  .leftJoin('auth_token', 'auth_token.user_id', 'user.id') 
  .where('user.email', 'like', '%some@email.com%')
  .andWhere('application.name', 'like' '%awesome-application%')

//...etc
0 голосов
/ 08 января 2019

Самое простое решение - это использование .whereRaw():

knex whereRaw

Пример:

.leftJoin('auth_token', 'auth_token.user_id', 'user.id')
.whereRaw('User.email LIKE ?', `${your_param_here}`)
.andWhereRaw('AuthToken.platform LIKE ?', `${your_param_here}`)
...