Knex: Abrufen der ID einer eingefügten Zeile

Erstellt am 10. März 2015  ·  13Kommentare  ·  Quelle: knex/knex

Wie füge ich etwas in eine Tabelle ein und gebe dann die ID der eingefügten Zeile zurück? Wenn man sich die Dokumentation ansieht, scheint es, als ob der folgende Code funktionieren sollte. Gibt es etwas, das ich vermisse?

var id = knex.insert(
  {
    first_name:firstName,
    last_name:lastName,
    email:email,
    phone_number:phoneNumber
  })
  .returning('id')
  .into('person')

Hilfreichster Kommentar

Bitte formatieren Sie Ihren Code in Zukunft mit der korrekten GitHub Flavored Markdown-Syntax, damit wir ihn lesen können.

Datenbankaufrufe sind asynchron, sodass Sie die Abfrage nicht einfach einer Variablen zuweisen können.

Korrekter Code würde so aussehen:

knex.insert({
  first_name: firstName,
  last_name: lastName,
  email: email,
  phone_number: phoneNumber
})
.returning('id')
.into('person')
.then(function (id) {
  // use id here
});

Alle 13 Kommentare

Bitte formatieren Sie Ihren Code in Zukunft mit der korrekten GitHub Flavored Markdown-Syntax, damit wir ihn lesen können.

Datenbankaufrufe sind asynchron, sodass Sie die Abfrage nicht einfach einer Variablen zuweisen können.

Korrekter Code würde so aussehen:

knex.insert({
  first_name: firstName,
  last_name: lastName,
  email: email,
  phone_number: phoneNumber
})
.returning('id')
.into('person')
.then(function (id) {
  // use id here
});

aus den docs:

insert.insert(data, [returning])
Erstellt eine Einfügeabfrage, die entweder einen Hash von Eigenschaften verwendet, der in die Zeile eingefügt werden soll, oder ein Array von Einfügungen, die als einzelner Einfügebefehl ausgeführt werden. Löst das Promise auf / erfüllt den Callback mit einem Array, das die erste Einfüge-ID des eingefügten Modells enthält, oder ein Array, das alle eingefügten IDs für postgresql enthält.

_was eigentlich nicht richtig / aktuell ist_

Wie oben gezeigt, löst der returning() Aufruf das Promise mit diesem Array auf – nicht der insert() Aufruf. Jetzt sieht es so aus, als könnten wir diese Funktion als zweiten Parameter übergeben, aber es ist schwer zu sagen, da die Dokumente etwas TLC benötigen.

@refactorized Tatsächlich returning(columnsToReturnFromDbWhenInsertsAreDoneForDatabasesWhichSupportsReturningStatement) Aufruf kein Versprechen auf.

Es fügt nur Informationen zu QueryBuilder dass Sie von dieser Einfügung diese Spalten nach der Einfügung zurückgeben sollten. Es hat also nichts mit dem Auslösen der Abfrage zu tun.

Wenn Sie die Dokumentationsseite überprüfen und auf Beispiele klicken, um beispielsweise den Postgres-Dialekt zu verwenden, sehen Sie in diesem Fall, was die returning Anweisung in der erstellten Abfrage ändert.

Auch die Dokumentation von .returning besagt klar, dass sein Parameter eine Spaltenliste ist und dass es nur mit unterstützten Datenbanken funktioniert.

@elhigu Danke für deine Klarstellung!

Was ich oben meinte, ist also, dass der Aufruf zum Zurückgeben das Verhalten des mit insert eingerichteten Promises ändert, sodass es jetzt ggf. mit der/den ID(s) aufgelöst wird. Ist das richtig?

Wenn ja, könnte es sich lohnen, diesem Punkt etwas mehr Nachdruck zu verleihen, da ich und ein paar Kollegen einige Zeit gebraucht haben, um herauszufinden, wie man abhängige Abfragen am besten miteinander verkettet, und dies ist ein sehr häufiger Anwendungsfall sowohl in Seed-Skripten als auch in komplizierte Einlagen.

Es ändert die Abfrage, die erstellt wird. zB mit postgres fügt es einfach returning "col1","col2","col3" etc. zu konstruierten Abfragen hinzu. Genau wie jede andere Methode im Abfrage-Generator. MySQL und sqlite unterstützen die Rückgabeanweisung überhaupt nicht.

z.B

> knex('table').insert({ foo: 'bar' }).toSQL()
{ method: 'insert',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings: [ 'bar' ],
  __knexQueryUid: 'e7d8d980-6fab-42e2-9240-75cb1af8ae21',
  sql: 'insert into "table" ("foo") values (?)',
  returning: undefined }
> 

Mit der Rückgabe einer konstruierten Abfrage geht das so:

> knex('table').insert({ foo: 'bar' }).returning('*').toSQL()
{ method: 'insert',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings: [ 'bar' ],
  __knexQueryUid: '27c2ad45-726d-410a-b585-2bd543e7bbbd',
  sql: 'insert into "table" ("foo") values (?) returning *',
  returning: '*' }

Wenn eine Abfrage an den Treiber gesendet wird, übergibt sie einfach sql und die Bindungen an den pg-Treiber und gibt das Versprechen zurück, um die Ergebnisse zu erhalten.

Wie setze ich CancelOnTimeout: false, auf true?

War es möglich, die ID mit knex.raw('insert ...'); ?

@roylee0704 Sie können das returning id in Ihre rohe SQL-Abfrage einfügen und es wird zurückgegeben:

var sql = `                                                          
  INSERT INTO users (email, oauth_provider, oauth_id)                
  VALUES (?, ?, ?)                                                   
  RETURNING *                                                        
`;                                                                   

knex                                                                 
  .raw(sql, ['[email protected]', 'waffles', 'pancakes'])              
  .then(function(result) {                                           
    // result.rows is the rows that were inserted, including all data
    console.log('rows', JSON.stringify(result.rows, null, 2));                                                  
  });                                                                

return('id') scheint zu einem Array zu führen, zB: [12] Ich habe Destrukturierung verwendet, um es herauszuholen:

const [userId] = await knex('table').insert(data).returning('id')

Für alle, die es in Zukunft brauchen:
Wie oben erwähnt, ergibt return('id') ein Array, sodass wir den Wert von id[0] erhalten können

knex('table name')
                .insert(dataset)
                .returning('id')
                .then(
                    function (id){
                         console.log(id[0]);  //id here
                    }
                )

Oder mit ES6-Destrukturierung kann das einfach sein:

knex('table name')
            .insert(dataset)
            .returning('id')
            .then(([id]) => console.log(id));  //id here

Ich habe eine Frage, die etwas nicht mit der Hauptfrage zu tun hat. Wie wird eine 'id' zurückgegeben, wenn keine id eingefügt wird?

Stack Overflow wäre wirklich ein besserer Ort für Fragen, aber:

A) Sie wissen nicht, dass dieser Code keine ID enthält (es könnte absolut ein dataset.id = 5 )

B) selbst wenn dies nicht der Fall war und Sie sich auf Sequenzen (z. B. Spalten vom seriellen Typ) verlassen, um Ihre IDs zu generieren, glaube ich, dass das Schlüsselwort "RETURNING" alle Werte zurückgeben kann, die im neu erstellten Datensatz vorhanden sind.

Außerdem ist mir aufgefallen, dass mein vorheriges Beispiel mit den zusätzlichen optionalen INSERT-Argumenten von Knex vereinfacht werden kann:

knex('table name')
        .insert(dataset, 'id')
        .then(([id]) => console.log(id));  //id here
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

nklhrstv picture nklhrstv  ·  3Kommentare

ghost picture ghost  ·  3Kommentare

mtom55 picture mtom55  ·  3Kommentare

aj0strow picture aj0strow  ·  3Kommentare

koskimas picture koskimas  ·  3Kommentare