2015-05-29 3 views
2

Действительно новый для node.js и относительно новый для PostgreSQL. По какой-то причине это создает только первую таблицу, а не вторую. Вероятно, я полностью ошибаюсь. Кажется, я не могу найти примеры кода, которые достаточно похожи, чтобы экстраполировать ответ. Я хочу создать две таблицы. Кажется, я могу запустить только один запрос, и все. Больше не надо. Предполагается, что мое соединение закончится до того, как будет выполнено второе. Я не знаю почему. Я не могу найти ни одного примера этого в десятках различных поисковых запросов Google.Как я могу выполнить несколько запросов (построить БД) в Node.JS?

var client = new pg.Client(connectionString); 
client.connect(); 
var query = client.query('CREATE TABLE preferences(id SERIAL PRIMARY KEY, food VARCHAR(40) not null, preferred BOOLEAN)'); 
client.query('CREATE TABLE foods(id SERIAL PRIMARY KEY, food VARCHAR(40) not null, type VARCHAR(40) not null, spicy BOOLEAN, spiciness VARCHAR(10)'); 
query.on('end', function() { client.end(); }); 

У меня были сомнения, что я мог бы просто сделать еще один client.query и завершить все это в конце. Я взял этот пример из учебника, но добавила вторую таблицу. Поэтому я просто играю с этим и пытаюсь учиться здесь с этим тестом.

Просто для того, чтобы заявить о своей конечной конечной цели: я хочу в конечном итоге создать целый сценарий для создания базы данных, полной полной всех необходимых таблиц и данных.

Ошибки я получаю независимо от того, что я пытаюсь:

$ узловые моделей/database.js events.js: 85 броска эр; // Ошибка Unhandled 'error ^ Ошибка: синтаксическая ошибка в конце ввода в Connection.parseE (~/Documents/test01/node_modules/pg/lib/connection.js: 534: 11) at Connection.parseMessage (~/Documents/test01/node_modules/pg/lib/connection.js: 361: 17) у Socket. (~/Documents/test01/node_modules/pg/lib/connection.js: 105: 22) на Socket.emit (events.js: 107: 17) на readableAddChunk (_stream_readable.js: 163: 16) на Socket .Readable.push (_stream_readable.js: 126: 10) at TCP.onread (net.js: 538: 20)

+0

Вы только ждали окончания одного из них, а не другого, так что вы, скорее всего, закончили соединение преждевременно. –

+0

Из того, что я собрал (уроки там ужасные), request.on ('end' ... part завершает соединение с db.Он получает бросок; // Необработанное событие «error» в ответе. На данный момент я все еще очень смущен. –

+0

'query.on (type, handler)' добавляет обработчик событий для переданного типа, «end» в этом случае. Когда это событие возникает для запроса, к которому вы его привязывали, срабатывает обработчик. Поэтому обработчик запускается, когда первый запрос завершен, что, вероятно, до завершения второго. –

ответ

4

Лучший способ - разместить все ваши запросы в транзакции и выполнить ее в одном и том же соединении.

Вот как вы можете сделать это с помощью pg-promise:

var pgp = require('pg-promise')(/*options*/); 
var db = pgp(connection); 

db.tx(t => { 
     return t.batch([ 
      t.none('CREATE TABLE preferences(id SERIAL, etc...'), 
      t.none('CREATE TABLE foods(id SERIAL PRIMARY KEY, etc...') 
     ]); 
    }) 
    .then(data => { 
     // success; 
    }) 
    .catch(error => { 
     console.log(error); // print error; 
    }); 

еще лучше, чтобы поместить все SQL к внешнему SQL files, для которых библиотека обеспечивает автоматическую поддержку.

+0

Да, ваша библиотека потрясающая;) – SneakyMummin

+0

@Caspinol Спасибо! :) –

2

Вы пытаетесь выполнить два асинхронных действия, поэтому вам нужно подождать, пока оба действия завершены, прежде чем продолжить. Один из способов сделать это - с переменной count.

var client = new pg.Client(connectionString); 
client.connect(); 
var query1 = client.query('CREATE TABLE preferences(id SERIAL PRIMARY KEY, food VARCHAR(40) not null, preferred BOOLEAN)'); 
var query2 = client.query('CREATE TABLE foods(id SERIAL PRIMARY KEY, food VARCHAR(40) not null, type VARCHAR(40) not null, spicy BOOLEAN, spiciness VARCHAR(10))'); 
var count = 2; 

function endHandler() { 
    count--; // decrement count by 1 
    if (count === 0) { 
     // two queries have ended, lets close the connection. 
     client.end(); 
    } 
} 

query1.on('end', endHandler); 
query2.on('end', endHandler); 

Обратите внимание, что в этом случае вы, вероятно, можете просто объединить два заявления в один, при условии, Postgres поддерживает, что и эту функциональность включена в вашей системе.

client.query('CREATE TABLE preferences(id SERIAL PRIMARY KEY, food VARCHAR(40) not null, preferred BOOLEAN);CREATE TABLE foods(id SERIAL PRIMARY KEY, food VARCHAR(40) not null, type VARCHAR(40) not null, spicy BOOLEAN, spiciness VARCHAR(10));') 
+0

(count === 0) Не означает ли три знака равенства эквивалентность по типу? –

+0

Да, похоже, это не работает, такая же ошибка: events.js: 85 throw er; // Необработанное событие «error» –

+0

три '=' - это тип и значение. я вообще всегда использую 3. –

1

Вам необходимо управлять несколькими «запросами» переменных. В вашем случае код может выглядеть следующим образом:

var client = new pg.Client(connectionString); 
     client.connect(); 
    var queryPreferences = client.query('CREATE TABLE preferences(id SERIAL PRIMARY KEY, food VARCHAR(40) not null, preferred BOOLEAN)'); 

    var foods = function() { 
     var queryFoods = client.query('CREATE TABLE foods(id SERIAL PRIMARY KEY, food VARCHAR(40) not null, type VARCHAR(40) not null, spicy BOOLEAN, spiciness VARCHAR(10)'); 
     queryFoods.on('end', function() { client.end(); }); 
    } 

    queryPreferences.on('end', foods); 

В этом случае вы запускаете второй запрос, пока вы не закончите первый, а затем вы закрываете соединение.

+0

Одна вещь, о которой я не уверен в вашем ответе, заключается в том, работает ли событие «конец», похожее на обещание, в том, что если конечное событие уже произошло, оно немедленно вызовет любые новые события или просто ничего не сделает потому что событие не произошло, поскольку обработчик был определен. однако в этом случае я не думаю, что это будет иметь значение, потому что «клиент» скорее всего отправляет запросы последовательно, а не параллельно, или db будет отвечать последовательно, а не параллельно. –

+0

Спасибо @KevinB и да, это был момент. Отправка запросов параллельно, поэтому вам нужно только закрыть соединение в конце последнего запроса. Обратите внимание, что второе событие ** end ** подписывается на ** ** queryFoods **. – Gepser

+0

Правильно, мое беспокойство было, что, если 'queryFoods' заканчивается первым? но, как я уже сказал, скорее всего, это не проблема, потому что это соединение db, которое обычно первое в первом случае, если не использовать отдельные соединения. –