Knex: Verbinden Sie zwei Tabellen über zwei verschiedene Schemas hinweg (eine Datenbank)

Erstellt am 23. Juli 2016  ·  3Kommentare  ·  Quelle: knex/knex

Hallo,
Wie können wir Tabellenverknüpfungen über zwei verschiedene Schemas hinweg, aber in derselben Datenbank implementieren?
Technisch gesehen sind Schemas nur eine logische Trennung von Tabellen innerhalb derselben Datenbank. Beim Schreiben einer SQL-Abfrage müssen wir ihnen also nur den Schemanamen voranstellen.
Beispielsweise,

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

Ich könnte wahrscheinlich unten kenx.js schreiben. Sieht das gut aus?

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

Aber dann sah ich. Option withSchema mit knex.js Was ist der Vorteil bei der Verwendung dieser Option, anstatt dem Tabellennamen ein Schema voranzustellen. Wie kann ich die Option .withSchema verwenden, um Join-Tabellen aus zwei verschiedenen Schemas zu verbinden?

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`

Hilfreichster Kommentar

Das Dokument sagt, dass die Identifier-Syntax, dh Tabellenname, Spaltenname, keinen Platz zum Auswählen des Schemas hat. Wenn Sie also schemaName.tableName ausführen, wird die Abfrage möglicherweise falsch gerendert.

Es wurde vorgeschlagen, stattdessen .withSchema('schemaName') zu verwenden.

Aber ich habe festgestellt, dass .withSchema im gesamten Builder-Block nur in einem Schema funktioniert.

Bisher habe ich folgende temporäre Sollutins:

  • Verwenden Sie .withSchema überhaupt nicht in Speasure-Abfragen, fügen Sie den Schemanamen in die Zeichenfolge des Tabellennamens ein.
    Dies gegen das Dokument.

  • Verwenden Sie die Unterabfrage mit .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)
    }

Auf diese Weise müssen Sie .as in der Unterabfrage verwenden.

  • Verwenden Sie .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)
    }
  • Verwenden Sie .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)
    }

Dies hat weniger Vorteile bei der Verwendung von Knex.

  • Verwenden Sie andere Bibliotheken oder ORMs oder Treiber.

Die letzte Kraft.

Alle 3 Kommentare

eine Lösung für diese?

Das Dokument sagt, dass die Identifier-Syntax, dh Tabellenname, Spaltenname, keinen Platz zum Auswählen des Schemas hat. Wenn Sie also schemaName.tableName ausführen, wird die Abfrage möglicherweise falsch gerendert.

Es wurde vorgeschlagen, stattdessen .withSchema('schemaName') zu verwenden.

Aber ich habe festgestellt, dass .withSchema im gesamten Builder-Block nur in einem Schema funktioniert.

Bisher habe ich folgende temporäre Sollutins:

  • Verwenden Sie .withSchema überhaupt nicht in Speasure-Abfragen, fügen Sie den Schemanamen in die Zeichenfolge des Tabellennamens ein.
    Dies gegen das Dokument.

  • Verwenden Sie die Unterabfrage mit .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)
    }

Auf diese Weise müssen Sie .as in der Unterabfrage verwenden.

  • Verwenden Sie .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)
    }
  • Verwenden Sie .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)
    }

Dies hat weniger Vorteile bei der Verwendung von Knex.

  • Verwenden Sie andere Bibliotheken oder ORMs oder Treiber.

Die letzte Kraft.

Fügen Sie der Antwort von @codinggirl ein weiteres Detail hinzu:

Mit joinRaw() können Sie die Parameter binden. Dadurch wird eine Abfrage mit einer identischen Syntax für die gesamte Abfrage generiert.

    {
        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)
    }

Hinweis: Positionsbindungen ? werden als Werte interpretiert und ?? werden als Bezeichner interpretiert.

Ausgabe mit Bindings auf PG:
Wählen Sie „Vorname“, „Nachname“, „Telefon“, „Site“, „Sites“. „Name“ als „Sname“ aus „Sandbox1“. "id" = "users".."site"

Ausgabe mit Bindungen auf MSSQL:
Wählen Sie [Vorname], [Nachname], [Telefon], [Site], [Sites].[Name] als [Sname] aus [Sandbox1].[Benutzer] verließen Join [public].[Sites] ON [Sites]. [id] = [Benutzer].[Website]

In der Zwischenzeit würde es ohne Bindung immer Folgendes generieren:
Wählen Sie „Vorname“, „Nachname“, „Telefon“, „Site“, „Sites“. „Name“ als „Sname“ aus „Sandbox1“. „Benutzer“ links Join public.sites ON sites.id = users.site

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

aj0strow picture aj0strow  ·  3Kommentare

fsebbah picture fsebbah  ·  3Kommentare

marianomerlo picture marianomerlo  ·  3Kommentare

koskimas picture koskimas  ·  3Kommentare

tjwebb picture tjwebb  ·  3Kommentare