select array[*список объектов*]::*нужный тип данных*[] select array_agg(*поле для агрегации* order by *поле для сортировки*)::*нужный тип данных*[] select array(select ...*подзапрос для агрегации*)::*нужный тип данных*[]
postgres=# select '{1, 2, 3}'::int[]; int4 --------- {1,2,3} (1 строка) про это спрашиваешь?
Есть таблица orders, там есть столбец products типа order_product[], тип создал таким образом CREATE TYPE order_product AS (id INTEGER,image TEXT,title TEXT,price NUMERIC(10, 0),color TEXT,size TEXT,count INTEGER); Теперь при попытке вставить данные в столбец products получаю ошибку
Показывай DDL таблицы orders, запрос и текст ошибки
Почему картинками
Опиши исходную задачу, зачем тебе в одной таблице массив со строками из другой
(id SERIAL PRIMARY KEY, orders CREATE TABLE IF NOT EXISTS user id INTEGER NOT NULL REFERENCES Tsers (id), products order product [ ] NOT NULL, INTEGER NOT delivery fee NULL DEFAULT 0, total INTEGER NOT NULL) ; :) На маке картинки не проблема. :))
Создание таблицы -CREATE TABLE IF NOT EXISTS orders (id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id), products order_product[] NOT NULL, delivery_fee INTEGER NOT NULL DEFAULT 0, total INTEGER NOT NULL); Вставка данных(в node js) - 'INSERT INTO orders (user_id, products, delivery_fee, total) VALUES ($1, $2, $3, $4) RETURNING * ;', [ req.user.userId, orderProducts, 15, total, ]
Для нормальных айтишников — проблема.
Можэшь внимательно прочитать картинку и сравнить со своим текстом.
Уже… Мак дурак… :)
one2many делается не так. Это строки в order_products должны ссылаться на orders.id, не наоборот. Это тебе не вложенные объекты
insert into orders_test (products) values ( ARRAY[(1,'test', 'test', 1.1, 'test', 'test', 1)]::order_product_test[] ); вот так работает insert
Кое-что в принцыпе потеряется в большынстве картинок (разница с и c, например).
По моему, скобки фигурные должны быть.
При вставки скобки фигурыми должны быть.. по моему..
>Вставка данных(в node js) - Попытка выполнить эту строку в js вызовет ошыбку синтаксиса. Приводите ДОСТАТОЧНО ПОЛНЫЙ текст процэдуры, чтобы было понятно — чем вы там занимаетесь. Все переменные, последние присвоения им, вызовы, относящиеся к переменным и базе данных. И все importы, которые нужны — чтобы было понятно, какие библиотеки используете. Лучшэ было бы, конечно, минимальный воспроизводимый пример — но это ладно, это понятно, это трудиться надо чтобы сделать. Это потом, если не поймём как выяснить вашы проблемы.
вот полная запись вставки const order = await db.query( 'INSERT INTO orders (user_id, products, delivery_fee, total) VALUES ($1, $2, $3, $4) RETURNING * ;', [ req.user.userId, orderProducts, 15, total, ] )
Кидал же скрин ошибки
Только текст, никаких скринов
Ах, скрин. Ну да, скрины тут не все читают, действительно (я, в том числе — не читаю).
Текстовым файлом или на pastebin.com/его аналог
А теперь — присвоения переменных и импорты этого файла!
вот весь код контроллера, если врям нужно все const createOrder = async (req, res) => { const { basketProducts } = req.body const orderProducts = [] let total = 0, count = 0 for (let item of basketProducts) { const basketProduct = await db.query( 'SELECT * FROM basket_product WHERE id = $1 AND basket_id = (SELECT id FROM basket WHERE user_id = $2)', [item.id, req.user.userId] ) if (!basketProduct.rows[0]) { throw new APIerror( No product in basket with id ${id}, StatusCodes.NOT_FOUND ) } const product = await db.query('SELECT * FROM products WHERE id = $1', [ item.product_id, ]) if (!product.rows[0]) { throw new APIerror( No product with id ${product_id}, StatusCodes.NOT_FOUND ) } const price = !!product.rows[0].discount ? Number(product.rows[0].price * (1 - product.rows[0].discount / 100.0)) : Number(product.rows[0].price) const orderProduct = { id: product.rows[0].id, image: product.rows[0].image, title: product.rows[0].title, price, color: basketProduct.rows[0].color, size: basketProduct.rows[0].size, count: basketProduct.rows[0].count, } orderProducts.push(orderProduct) total += orderProduct.price * orderProduct.count count += orderProduct.count } const order = await db.query( 'INSERT INTO orders (user_id, products, delivery_fee, total) VALUES ($1, $2, $3, $4) RETURNING * ;', [ req.user.userId, orderProducts, 15, total, ] ) return res.status(StatusCodes.CREATED).json({ order: order.rows[0] }) }
Да, так значительно понятнее.
вот импорты const { StatusCodes } = require('http-status-codes') const db = require('../db/db') const { APIerror } = require('../services/API-error')
Осталось выяснить как минимум — библиотеку, которая используется для работы с постгресом (я вижу как минимум дву — pg и posgres), ну и ошыбку.
И что там в ../db/db ?
const Pool = require('pg').Pool const pool = new Pool({ user: 'postgres', host: 'localhost', database: process.env.DB_NAME, password:process.env.DB_PASSWORD, port: 5432, }) module.exports = pool
а какая разница какую библиотеку он использует, если он пишет по сути нативный sql? у него объект, который при вставке через параметры меняет тип и конструкция sql запроса которая формируется просто не правильная получается
да, проблема в ставке
Ну и да, ладно, б-г с ней, с ошыбкой. Подозреваю, что этот pg в принцыпе не имеет кода для преобразования чего бы то ни было в row (или record) в постгресе. Потому собирать это придётся так или иначе самому. Вот каждую запись того массива — вместо javascript object — преобразовать в какой-нибудь текст вида 'row()' ... Как это конкретно лучшэ сделать — можно подумать. Или подумать о том, что вы делаете, похожэ, что-то не то. Вообще, примерно 99% использований массивов в постгресе — используются совершэнно зря (в том числе, по-моему, зря их используются в ядре постгреса для acl).
Разница в том, что это именно библиотека преобразует внутренние типы javascript в параметры в протоколе постгреса. И ключевой вопрос — можэт ли она как-нибудь преобразовать object/array/etc в row/array/etc.
одно дело преобразовать просто тип - строка, число, возможно умеет int[] и подобные, другое кастомный тип, про который библиотека даже не знает
и вряд ли она соберёт такую конструкцию
Обсуждают сегодня