Knex: Unir dos tablas en dos esquemas diferentes (una base de datos)

Creado en 23 jul. 2016  ·  3Comentarios  ·  Fuente: knex/knex

Hola,
¿Cómo podemos implementar la combinación de tablas en dos esquemas diferentes pero en la misma base de datos?
Técnicamente, los esquemas son solo una separación lógica de tablas dentro de la misma base de datos, por lo que al escribir una consulta SQL, todo lo que necesitamos es prefijarlos con el nombre del esquema.
Por ejemplo,

select * 
from user_schema.users as users
inner join account_schema.accounts  as accounts
on users.users.id = accounts.user_id

Probablemente podría escribir debajo de kenx.js. ¿Se ve bien?

knex.from('user_schema.users as users').innerJoin('account_schema.accounts as accounts', 
'users.id', 'accounts.user_id')

Pero luego vi. withSchema opción con knex.js ¿Cuál es la ventaja de usar esa opción en lugar de prefijar el nombre de la tabla con el esquema. ¿Cómo puedo usar la opción .withSchema para unir tablas de dos esquemas diferentes?

Knex.js Documentation 
------------------------
.withSchema([schemaName]) 
Specifies the schema to be used as prefix of table name.

knex.withSchema('public').select('*').from('users')

Outputs:
select * from `public`.`users`

Comentario más útil

El documento dice Sintaxis de identificador, es decir, nombre de tabla, nombre de columna, no tiene lugar para seleccionar el esquema, por lo que si está haciendo schemaName.tableName, la consulta podría generarse incorrectamente.

Sugirió usar .withSchema('schemaName') en su lugar.

Pero encontré que .withSchema solo funciona en un esquema en todo el bloque de construcción.

Hasta ahora, tengo las siguientes soluciones temporales:

  • No use .withSchema en absoluto en la consulta específica, incluya el nombre del esquema en la cadena del nombre de la tabla.
    Esto contra el documento.

  • Usar subconsulta con .withSchema

    {
        let rows = await knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .leftJoin(
                knex.withSchema('public')
                    .table('sites')
                    .select()
                    .as("sites"),
                "sites.id",
                "users.site")
        console.log(rows)
    }

De esta manera necesita usar .as en la subconsulta.

  • Usa .joinRaw()
    {
        let queryBuilder = knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .joinRaw("left join public.sites as sites ON sites.id = users.site", [])
        let sql = queryBuilder.toSQL().toNative()
        let rows = await queryBuilder

        console.log((sql))
        console.log(rows)
    }
  • Usa .raw()
    {
        let { rows ,rowCount } = await knex
            .raw('SELECT users.first_name, users.last_name, users.phone, users.site, sites.name as sname FROM sandbox1.users, public.sites WHERE sites.id = users.site;');

        console.log(rows)
    }

Esto tiene menos beneficios para usar knex.

  • Use otra biblioteca u ORM o controladores.

El poder final.

Todos 3 comentarios

alguna solucion para este?

El documento dice Sintaxis de identificador, es decir, nombre de tabla, nombre de columna, no tiene lugar para seleccionar el esquema, por lo que si está haciendo schemaName.tableName, la consulta podría generarse incorrectamente.

Sugirió usar .withSchema('schemaName') en su lugar.

Pero encontré que .withSchema solo funciona en un esquema en todo el bloque de construcción.

Hasta ahora, tengo las siguientes soluciones temporales:

  • No use .withSchema en absoluto en la consulta específica, incluya el nombre del esquema en la cadena del nombre de la tabla.
    Esto contra el documento.

  • Usar subconsulta con .withSchema

    {
        let rows = await knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .leftJoin(
                knex.withSchema('public')
                    .table('sites')
                    .select()
                    .as("sites"),
                "sites.id",
                "users.site")
        console.log(rows)
    }

De esta manera necesita usar .as en la subconsulta.

  • Usa .joinRaw()
    {
        let queryBuilder = knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .joinRaw("left join public.sites as sites ON sites.id = users.site", [])
        let sql = queryBuilder.toSQL().toNative()
        let rows = await queryBuilder

        console.log((sql))
        console.log(rows)
    }
  • Usa .raw()
    {
        let { rows ,rowCount } = await knex
            .raw('SELECT users.first_name, users.last_name, users.phone, users.site, sites.name as sname FROM sandbox1.users, public.sites WHERE sites.id = users.site;');

        console.log(rows)
    }

Esto tiene menos beneficios para usar knex.

  • Use otra biblioteca u ORM o controladores.

El poder final.

Agregando un detalle más a la respuesta de @codinggirl :

Usando joinRaw() puede vincular los parámetros. Lo que genera una consulta con una sintaxis idéntica en toda la consulta.

    {
        const queryBuilder = knex.withSchema("sandbox1")
            .select('first_name', 'last_name', 'phone', 'site', "sites.name as sname")
            .from('users')
            .joinRaw("left join ?? ON ?? = ??", ["public.sites", "sites.id", "users.site"])
        const sql = queryBuilder.toString()
        console.log(sql)
    }

Nota: enlaces posicionales? se interpretan como valores y ?? se interpretan como identificadores.

Salida con enlaces en PG:
seleccione "nombre", "apellido", "teléfono", "sitio", "sitios"."nombre" como "sname" de "sandbox1"."usuarios" dejados unirse a "público"."sitios" ON "sitios". "id" = "usuarios"."sitio"

Salida con enlaces en MSSQL:
seleccione [first_name], [last_name], [phone], [site], [sites].[name] as [sname] from [sandbox1].[users] left join [public].[sites] ON [sites]. [id] = [usuarios].[sitio]

Mientras tanto, sin vinculación, siempre generaría:
seleccione "nombre", "apellido", "teléfono", "sitio", "sitios"."nombre" como "sname" de "sandbox1"."usuarios" dejados unirse a public.sites ON sites.id = usuarios.sitio

¿Fue útil esta página
0 / 5 - 0 calificaciones