Форум программистов, компьютерный форум, киберфорум
Go (Golang)
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/23: Рейтинг темы: голосов - 23, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 17.03.2021
Сообщений: 6
1

Как записать срез байтов в Базу данных SQL

17.03.2021, 01:15. Показов 4729. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток. В рамках обучения получил задание, взять данные с сайта https://jsonplaceholder.typicode.com, а именно посты и комментарии к ним и записать в базу данных SQL, само собой привязав комментарии к постам. У меня не возникло никаких проблем с помощью GET получить данные с сайта и вывести их в консоль или создавать новый файл. Так же я понимаю как с помощью db.ExecContext или аналога добавить данные в БД. Но при попытках записать полученные данные в Бд я получаю закономерное несоответствие типов данных. Как это исправить?

P.S. Данные почему-то принимаются не строкой, а ровно так как выглядят на сайте
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.03.2021, 01:15
Ответы с готовыми решениями:

Необходимо файл (любого расширения) записать в базу данных как массив байтов
Необходимо файл (любого расширения) записать в базу данных в byte форме. И затем взять его (выбрав...

Записать DataTable в базу SQL с сохранением структуры данных
Здравствуйте! Создал DataSet1. В нем создал DataTable1. Заполнил таблицу через самописный...

Программно из таблицы Word записать данные в базу данных SQL
Здравствуйте, можно это сделать? таблица из двух столбцов, и для общего развития база данных SQL,...

Записать значение null в поле c датой из программы в базу данных sql
Есть программа на с# и бд на sql. В sql есть таблица с полем типа данных date. Эта таблица...

9
59 / 51 / 29
Регистрация: 30.12.2015
Сообщений: 162
17.03.2021, 21:30 2
Gorm используете для работы с базой? Если нет, то рекомендую, в этой либе есть всё что необходимо, особенно автомиграция прикольная штука. Но если совсем ничего не получится, всегда можно преобразовать данные в base64 и записать в поле с типом text(но это костыль, если задача на один раз, так делать плохо)
1
0 / 0 / 0
Регистрация: 17.03.2021
Сообщений: 6
18.03.2021, 23:24  [ТС] 3
Для базы использую db.Exec и в целом пакет db. Мне до этого посоветовали подробнее изучить пакет json и маршалинг
0
59 / 51 / 29
Регистрация: 30.12.2015
Сообщений: 162
19.03.2021, 18:26 4
Magus, Ну в json нельзя записать массив байт в прямом виде) функция json.Marshal() преобразует []byte в строку base64 Да и это никак не поможет записать данные в базу, вот пример записи в бд с помощью Gorm

1 - Создаём структуру с описание полей таблицы
и имплементируем интерфейс tabler

Go
1
2
3
4
5
6
7
8
9
10
type Photo struct {
    ID            int    `json:"id,omitempty" gorm:"column:ID"`
    PreviewRaster []byte `json:"previewRaster,omitempty" gorm:"column:PREVIEW_RASTER"`
    HiresRaster   []byte `json:"hiresRaster,omitempty" gorm:"column:HIRES_RASTER"`
    TS            int    `json:"ts,omitempty" gorm:"column:TS"`
}
 
func (Photo) TableName() string {
    return "photo"
}
документашка на коннект к бд через горм
Потом при старте приложения вызываем метод AutoMigrate() у экземпляра коннекта к db (*gorm.DB)
Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//тут коннект к бд через горм (gormDb)
 
photo:= new(Photo)
 
res := gormDb.AutoMigrate(photo)// на этом этапе в базе данных создаётся наша таблица
if res.Error != nil  {
     panic(res.Error)
}
 
photo.Id = 0
// тут заполняем остальные поля из photo
res = gormDb.Create(photo)
if res.Error != nil  {
     panic(res.Error)
}
//а тут радуемся нашим данным в базе :))))
Добавлено через 28 минут
А вот теперь я посмотрел вашу ссылку, там вообще не нужен массив байт, вы можете ответ напрямую десереализовать в json

Вот есть класная штука, которая json из ответа превратит в структуру и останется только добавить ей гормовский теги и создать такую таблицу в бд с помощью миграции
1
0 / 0 / 0
Регистрация: 17.03.2021
Сообщений: 6
19.03.2021, 19:26  [ТС] 5
Штуку и правда классная, экономия времени в чисто виде.
Как я понял, я задаю типа который = моей таблице в БД. Задаю переменную этого типа и с помощью автомиграции получаю новую таблицу(или обновление если она уже есть). С помощью Create записываем данные в БД. Но остался момент в котором я не уверен. Как нашей переменной(в данном случае photo) задать значение с сайта.
Я на данный момент использую такую структуру получения данных. Разве что я не понимаю как более удобно( к примеру через цикл) получить определенные посты, к пример с 60-65, кроме как вручную записывать их.
Go
1
2
3
4
5
6
7
8
9
10
resp, err := http.Get("https://jsonplaceholder.typicode.com/comments?postId=1")
    if err != nil {
        log.Fatal(err)
    }
 
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
    }
    defer resp.Body.Close()
Так вот Если я присвою photo=body оно нормально среагирует? Особенно это волнует при получение нескольких структур.

И небольшой оффтоп. "и имплементируем интерфейс tabler"
Go
1
2
3
func (Photo) TableName() string {
    return "photo"
}
Много раз видел этот участок кода или нечто похожее, но нигде не было написано зачем именно эта функция или я не очень сопоставил теорию и практику

P.S. Большое спасибо и за ту помощь что уже предоставил, прости что прошу ещё больше информации.
0
59 / 51 / 29
Регистрация: 30.12.2015
Сообщений: 162
21.03.2021, 21:19 6
Лучший ответ Сообщение было отмечено Magus как решение

Решение

Magus, сразу скажу, что photo приведено просто для примера и взято из моего кода, у вас скорее будет называться просто тест, с необходимыми вам полями. Вы же на данный момент используете не структуру, а просто получаете данные с сайта в в виде []byte и конечно photo=body не сработает, необходимо использовать метод json.Unmarshal(body,photo). В данном случае вам необходимо взять json что возвращается на ваш запрос и преобразовать его в структуру на том сайте, что я кидал выше. И для это структуры имплементировать интерфейс tabler, придумав ей название(на счёт вопроса что такое имплементация интерфейса и вообще интерфейсы, это базовая информация, без которой разрабатывать в стиле ооп просто невозможно, могу только скинуть , так как объяснять такие вещи не вижу смысла, сорри).


На данный запрос вам возвращается массив объектов, для данного запроса структура описывающая один элемент ответа на запрос будет выглядеть вот так
Go
1
2
3
4
5
6
7
type Test struct {
    PostID int    `json:"postId"`
    ID     int    `json:"id"`
    Name   string `json:"name"`
    Email  string `json:"email"`
    Body   string `json:"body"`
}
Встаёт вопрос как сделать так, что получить массив таких структур, очень просто, например вот так

Go
1
type Tests []*Test
А используем мы всё это вот так

Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
type Tests []*Test
 
type Test struct {
    PostID int    `json:"postId"`
    ID     int    `json:"id"`
    Name   string `json:"name"`
    Email  string `json:"email"`
    Body   string `json:"body"`
}
 
func (Test) TableName() string {
    return "test"
}
 
resp, err := http.Get("https://jsonplaceholder.typicode.com/comments?postId=1")
    if err != nil {
        log.Fatal(err)
    }
 
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
    }
    defer resp.Body.Close()
    tests:= make(Tests,0)
    err := json.Unmarshal(body, &tests )
    if err != nil {
        fmt.Println(err)
    }
    for test := tests {
         res = gormDb.Create(test)
         if res.Error != nil  {
            panic(res.Error)
          }
    }
Как я понял, я задаю типа который = моей таблице в БД.
Это экземпляр подключения не к таблице, а к базе данных, это разные вещи, в базе может быть сколько угодно таблиц, и через эту переменную вы можете получить\записать данные в любую из них

Добавлено через 56 минут
P.S.
Форум потёр ссылку на сайт с описанием, что такое интерфейсы, прикладываю другую, здесь не только про интерфейсы но и в целом про ООП, рекомендую прочитать всё.
1
0 / 0 / 0
Регистрация: 17.03.2021
Сообщений: 6
25.03.2021, 12:51  [ТС] 7
Спасибо большое, особенно за ссылку. Я когда учил базисы меньше всего понял структуры и особенно интерфейсы, если с структурой ещё понятно стало с практикой, то интерфейсы надеюсь хоть теперь пойму.
Цитата Сообщение от Nikita12211 Посмотреть сообщение
так как объяснять такие вещи не вижу смысла, сорри).
Так какое тут сори, этот пост и так существенно увеличил мои знания, а я сначала очень не хотел писать на форумы, стыдно было что-ли

Надеюсь последний мой вопрос, который меня давно мучает
Цитата Сообщение от Nikita12211 Посмотреть сообщение
resp, err := http.Get("https://jsonplaceholder.typicode.com/comments?postId=1")
Вот тут можно вместо postId=1, вставить переменную? Точнее я уже пробовал вставить переменную напрямую, но никакие мои выверты не помогли обмануть систему и всё кроме четкой цифры отвергалось.Или всё же для каждого поста нужно будет создать отдельную функцию?
0
59 / 51 / 29
Регистрация: 30.12.2015
Сообщений: 162
25.03.2021, 14:14 8
Magus, тут ничего обманывать не надо)
Go
1
2
postId:= 1
fmt.Sprintf("https://jsonplaceholder.typicode.com/comments?postId=%d", postId)
данный метод позволяет компоновать строки как захочется. Вот тут, описаны все возможные форматы, но я чаще всего использую %v(go сам определит тип переменной и подставит в строку)

Добавлено через 8 минут
Magus, но и это не совсем хорошая практика, есть специальная либа для компановки урла,

Go
1
2
3
4
5
6
7
8
    commentsUrl, err := url.Parse("https://jsonplaceholder.typicode.com/comments")
    if err != nil {
        return nil, fmt.Errorf("invalid URL: %s", err.Error())
    }
        postId:= "1"
    url.Query().Add("postId",postId)
 
        resp, err := http.Get(commentsUrl.String())
1
0 / 0 / 0
Регистрация: 17.03.2021
Сообщений: 6
29.03.2021, 19:39  [ТС] 9
Для Sprint вопросов нет, данный формат я освоил плюс минус, как минимум о нём знаю. Сам использую как напоминалку вот этот сайт. Но мне то нужно для GET, что-бы записывать разные посты в БД. Но как я понял использовать библиотеку url будет лучшим вариантом и не нужно никаких костылей и прочего.
0
0 / 0 / 0
Регистрация: 17.03.2021
Сообщений: 6
04.04.2021, 18:57  [ТС] 10
Nikita12211,
Цитата Сообщение от Nikita12211 Посмотреть сообщение
for test := tests {
expected boolean or range expression, found assignment (missing parentheses around composite literal?)syntax


Добавлено через 2 часа 40 минут
Открыл я свою БД и увидел там test
В результате подключился то я правильно, а данные упорно отказываются записываться
Версия с gorm:
https://play.golang.org/p/8KA6Nc0g7D5
Версия с sql
https://play.golang.org/p/-XMYfGfKUjw
0
04.04.2021, 18:57
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.04.2021, 18:57
Помогаю со студенческими работами здесь

Как выгрузить базу данных 1с 8.2 с SQL сервера в новую созданную локальную базу?
Добрый день! Возникла следующая проблема, при работе в конфигураторе с базой которая находится на...

Записать картинку в виде массива байтов в базу а потом оттуда вывести на страницу в браузере
Нужно записать картинку в виде массива байтов в базу а потом от туда вывести на страницу в...

Добавление записей из базу данных Access в базу данных SQL
Здравствуйте,пытаюсь добавить записи из базы данных Access в базу данных SQL,но не могу разобраться...

Как записать изображение в базу данных
как вместе с текстом сообщения ( вопроса ) прикрепить изображение ( картинку ) , наверное файл...

Как записать массив в базу данных
Добрый день) Помогите пожалуйста писать запрос на Sql-e Вот задача В метод приходит два ...

Как записать информацию в базу данных?
Здравствуйте. У меня есть: - база данных, которую я добавил в проект - далее из окна...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru