У меня есть две таблицы в базе данных облачного гаечного ключа Google - Авторы и Книги.
const request = {schema: [CREATE TABLE Authors (
AuthorId INT64 NOT NULL,
FirstName STRING(1024),
LastName STRING(1024),
AuthorInfo BYTES(MAX)
) PRIMARY KEY (AuthorId)
, CREATE TABLE Books (
AuthorId INT64 NOT NULL,
BookId INT64 NOT NULL,
BookTitle STRING(MAX)
) PRIMARY KEY (AuthorId, BookId),
INTERLEAVE IN PARENT Authors ON DELETE CASCADE
,],};
export async function findAuthorBooks(authorId) {
// [START spanner_find_author_books]
const database = instance.database(databaseId);
const query = {
sql: "SELECT * FROM Books As t WHERE t.AuthorId = @authorId",
params: { authorId },
types: { authorId: "string" },
};
const results = await database.run(query);
const rows = results[0];
const result = [];
rows.forEach((row) => {
const json = row.toJSON();
result.push(json);
});
database.close();
if (Array.isArray(result)) return result;
throw new Error("err");
// [END spanner_find_author_books]
}
Теперь я хочу запросить всех авторов и для каждого автора я запрашиваю всеего книги и добавить его как объект.Функция findAuthor1 () прекрасно работает.
export async function findAuthors1() {
// [START spanner_find_authors]
const database = instance.database(databaseId);
const results = await database.run({ sql: "SELECT * FROM Authors" });
const rows = results[0];
const result = [];
for (const row of rows) {
const json = row.toJSON();
const id = json.vendorId;
json.notification = await findAuthorBooks(id);
result.push(json);
}
database.close();
if (Array.isArray(result)) return result;
throw new Error("err");
// [END spanner_find_authors]
}
Но проблема здесь в том, что итераторам / генераторам требуется время выполнения регенератора, которое слишком тяжело для этого руководства, чтобы их разрешить.Отдельно следует избегать циклов в пользу итераций массива (согласно Eslint).Итак, я решил использовать Promise.all, как показано ниже в функции findAuthors2 ():
export async function findAuthors2() {
// [START spanner_find_authors]
const database = instance.database(databaseId);
const results = await database.run({ sql: "SELECT * FROM Authors" });
const rows = results[0];
const result = [];
await Promise.all(rows.map(async (row) => {
const json = row.toJSON();
const id = json.vendorId;
json.notification = await findAuthorBooks(id);
result.push(json);
}));
database.close();
if (Array.isArray(result)) return result;
throw new Error("err");
// [END spanner_find_authors]
}
К сожалению, она не работает.Итак, как я могу заставить это работать или есть другой (лучший) способ сделать это без необходимости использовать Promise.all?Или есть способ написать подзапрос, который выберет Книги в качестве массива структур и добавит к основному запросу, выбрав Авторы?