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`
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.
.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)
}
.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.
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
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
De esta manera necesita usar
.as
en la subconsulta..joinRaw()
.raw()
Esto tiene menos beneficios para usar knex.
El poder final.