Гость
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / JSON to Object (ID) / 25 сообщений из 30, страница 1 из 2
31.03.2016, 21:10
    #39205487
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Есть задача открыть объект, преобразовать его в JSON, как-то его поправить и обратно из JSON сохранить.
В этот момент у меня возникает проблема, при преобразовании JSON в объект методом ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject() теряется id, объект получается как будто новый. Соответственно, при сохранении он и ведет себя как новый.
Есть ли возможность при конвертации json в объект штатными средствами подхватывать и изменять уже существующие сохраненные объекты? Как вы разрешали для себя такую ситуацию?

Пример могу соорудить, но мне кажется, что те, кто с этим сталкивался, и так в курсе проблемы.
...
Рейтинг: 0 / 0
01.04.2016, 09:43
    #39205716
О-О-О
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Блок А.Н.,

Зачем так сложно.
Преобразовать, затем самому подправить, затем назад преобразовать?
Смысл вообще не понятен.
...
Рейтинг: 0 / 0
01.04.2016, 09:45
    #39205722
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Блок А.Н.Есть задача открыть объект, преобразовать его в JSON, как-то его поправить и обратно из JSON сохранить.
Есть ли возможность при конвертации json в объект штатными средствами подхватывать и изменять уже существующие сохраненные объекты? Как вы разрешали для себя такую ситуацию?Например:
Код: plaintext
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.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
Class my.test Extends %Persistent
{

Property f As %Integer [ InitialExpression = 5 ];

ClassMethod Test(case = "")
{
  d ..%KillExtent()
  d ..%New().%Save()
  
  s obj=..%OpenId(1)
  w "До: f = ",obj.f,!
  
  if case="" {
    ; преобразовываем наш объект в объект JSON (тип %Object, не строка!)
    s json={"returnValue":obj}
    w "(test1) json = ",$classname(json),!
    
    s json.returnValue.f=3 ;меняем значение свойства
    
    ; преобразовываем JSON обратно в наш тип %RegisteredObject
    d obj.$compose(json)
  }else{
    ; преобразовываем наш объект в объект JSON (тип %Object, не строка!)
    s json=({}).$fromObject(obj)
    /*
    ; или так
    ; преобразовываем наш объект сначала в JSON-строку, потом в объект JSON (тип %Object)
    s json=({}).$fromJSON(obj.$toJSON())
    */

    w "(test2) json = ",$classname(json),!
    
    s json.f=3 ;меняем значение свойства

    ; преобразовываем JSON-объект обратно в наш тип %RegisteredObject
    d json.$compose(obj)
  }
  
  ;сохраняем как обычно
  d obj.%Save()
  k obj

  w "После: f = ",..%OpenId(1).f
}

}
Результат:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
USER>d ##class(my.test).Test()
До: f = 5
(test1) json = %Library.Object
После: f = 3
USER>d ##class(my.test).Test(1)
До: f = 5
(test2) json = %Library.Object
После: f = 3
USER>
...
Рейтинг: 0 / 0
01.04.2016, 09:48
    #39205725
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
О-О-ОБлок А.Н.,

Зачем так сложно.
Преобразовать, затем самому подправить, затем назад преобразовать?
Смысл вообще не понятен.Наверное потому, что этапБлок А.Н.Есть задача открыть объект, преобразовать его в JSON, как-то его поправить и обратно из JSON сохранить.должен будет происходить вне Caché?
...
Рейтинг: 0 / 0
01.04.2016, 11:49
    #39205868
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
servit,

да, этап правки объекта должен проходить на клиенте в браузере. Мне показалось что json хороший способ передачи объектов каше в яваскрипт и обратно и что так все делают.

Пример не получилось скомпировать, у нас на рабочей версия каше 2014, у меня на компе стоит 2015.2, по-видимому, 2016 только вышла. Но все равно он не отражает суть того, что мне нужно.

Мне приходит из клиента некий json, включающий в себя в том числе и id, и мне нужно из него создать объект, причем, если указан id, заменить хранимый объект в базе. В примере же мы открываем объект, и в него "заливаем" некий json. В моем случае я не знаю, какой объект мне открывать и по сути создаю его заново, но создать хочу уже с ID, чтобы при сохранении он затер существующий.

Пока я вижу два пути, и оба они мне очень не нравятся:
- превратить json в %ZEN.proxyObject, посмотреть, если ли там ID, если есть, то открыть объект и присвоить в него поля из %ZEN.ProxyObject
- написать свой парсер.
...
Рейтинг: 0 / 0
01.04.2016, 18:11
    #39206293
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Блок А.Н.Но все равно он не отражает суть того, что мне нужно.
А теперь?Пример для 2016.2
Код: plaintext
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.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
Class my.test Extends %Persistent
{

Property f As %Integer [ InitialExpression = 5 ];

/// d ##class(my.test).Test()
ClassMethod Test()
{
  #define JSONUpsert(%json) $s(%json."_id"="":$system.OBJ.New(%json."_class"),1:$system.OBJ.OpenId(%json."_class",%json."_id"))
  
  d ..%KillExtent()
  d ..%New().%Save()
  
  s obj1=..%OpenId(1) ; или ..%New()
  
  ; отправляем клиенту JSON-строку
  w "<- f = ",obj1.f,!,"<- json = ",obj1.$toJSON(),!!
  
  ; меняем наш JSON где-то на стороне и получаем его обратно. 
  ; допустим мы получили это
  
  s jsonStr="{""_class"":""my.test"",""_id"":""1"",""f"":3}"
  w "-> json = ",jsonStr,!
  
  ; преобразовываем JSON-строку в JSON-объект
  s json=({}).$fromJSON(jsonStr)
  
  ; создаём или открываем объект нужного типа (и с нужным ID)
  s obj2=$$$JSONUpsert(json)
  ; заполняем его данными из JSON-объекта 
  d json.$compose(obj2)

  ;сохраняем как обычно
  d obj2.%Save()
  k obj2

  w "-> f = ",..%OpenId(1).f
}

/// Дополнительно к встроенному поведению, также присваиваем значения свойствам _class и _id
Method %ToDynamicObject(
  target As %Object = "",
  ignoreUnknown = 0) [ ServerOnly = 1 ]
{
  s:target="" target = {}
  s target."_class" = $classname() 
  s target."_id" = ..%Id()
  d ##super(.target,.ignoreUnknown)
}

}
Результат:

Код: plaintext
1.
2.
3.
4.
5.
6.
USER>d ##class(my.test).Test()
<- f = 5
<- json = {"_class":"my.test","_id":"1","f":5}
 
-> json = {"_class":"my.test","_id":"1","f":3}
-> f = 3
USER>
Для более старых версий легко можно сделать только отправку:
Код: plaintext
1.
 d ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(.stream,..%OpenId(1),,,1,"aelqoc")
 w "<- json = ",stream.Read(),!
С заполнением уже открытого объекта из JSON придётся писать велосипед.
...
Рейтинг: 0 / 0
01.04.2016, 19:18
    #39206340
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
servit,

Значит, велосипед, жаль.
И даже в новых версиях без костылька не взлетает :-(.
Спасибо.
...
Рейтинг: 0 / 0
02.04.2016, 09:03
    #39206532
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Поправил ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject()
Совсем нехорошо, но проще всего. Писать свой парсер лень, да и безглючно я его не напишу. Скопировать код IS в свой класс можно, что что-то меня от этого тоже останавливает.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Вместо

Set pObject = $classmethod(tClass,"%New")

теперь

s id = $G(tPropValues("_id"))
if id = "" 
{
 s pObject = $classmethod(tClass,"%New")
}
else 
{
 s pObject = $classmethod(tClass,"%OpenId",id)
}
...
Рейтинг: 0 / 0
08.07.2016, 19:24
    #39270864
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
servit

Добрались руки до того, чтобы пощупать новые версии Каше.
Пытаюсь запустить ваш код - не получается.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
USER>w $zv
Cache for Windows (x86-32) 2016.1.1 (Build 107U) Sat Jun 11 2016 19:32:35 EDT
USER>d ##class(my.test).Test()
До: f = 5
(test1) json = %Library.Object
 
    d obj.$compose(json)
    ^
<METHOD DOES NOT EXIST>zTest+11^my.test.1 *$compose,my.test
В какой версии появляются $compose, $fromObject? Вроде использую самую новую официально выпущенную на текущий момент
...
Рейтинг: 0 / 0
08.07.2016, 19:31
    #39270866
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Вообще смотрю я на это все и не понимаю.
Вроде бы все хорошо, сделали поддержку JSON, только %Object живет своей жизнью, а все остальные классы своей и друг с другом не пересекаются. Наверное в этом бы какой-то смысл, может быть идеологическая чистота или еще что-нибудь такое, только зачем она нужна в этом случае? В одной пробирке две не смешивающиеся жидкости.

Я понимаю, что еще практически еще ни в чем не разобрался и в своей манере полез писать на форум, но первая эмоция именно такая - недоумение.
...
Рейтинг: 0 / 0
09.07.2016, 16:25
    #39271113
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Блок А.Н.Пытаюсь запустить ваш код - не получается.Правильно не получается.
Будьте внимательны, я указал минимальную версию Caché для работы примера: 19006466 Блок А.Н.Вообще смотрю я на это все и не понимаю.
Вроде бы все хорошо, сделали поддержку JSON, только %Object живет своей жизнью, а все остальные классы своей и друг с другом не пересекаются.Это не так.
В версиях 2016.(2/3) интеграция JSON с SQL, объектами и "Caché Document Data Model", а также его производительность существенно улучшены и это не предел. Работа ведётся и дальше: кое какие улучшения запланировали на 2016.4/2017.1, а некоторые уже решили в 2016.3.
...
Рейтинг: 0 / 0
10.07.2016, 15:44
    #39271374
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
servit,

понятно, спасибо. Получается, пока без костылей и самоделок не обойтись даже на новых версиях. Значит ждем.
...
Рейтинг: 0 / 0
11.07.2016, 09:22
    #39271593
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Блок А.Н.понятно, спасибо. Получается, пока без костылей и самоделок не обойтись даже на новых версиях. Значит ждем.Для хранения, извлечения, обновления непосредственно JSON-объектов добавили новую модель данных - Caché Document Data Model (сокращённо DocDM).
В которой можно индексировать данные для ускорения выборки, использовать готовый REST API, SQL и/или JSON Path Language, хранить любые JSON-объекты. Причём в этой модели необязательно, чтобы набор полей в коллекции "однотипных" экземпляров совпадал.
Вот небольшой пример с демонстрацией лишь некоторых возможностей:
Код: plaintext
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.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
s db = ##class(%DataModel.Document.Database).$getDatabase()

;удаляем данные от предыдущих тестов
d db.$dropCollection("test")

;получаем коллекцию наших объектов
s coll = db.$getCollection("test")

; сохраняем некий объект в БД
d coll.$insert({"id":1,"поле 1":"значение 1","a":true,"b":null}) 
; вставляем или обновляем другой объект в БД с documentID=2
d coll.$upsert(2,{"id":1,"поле 2":"значение 2","a":false,"b":"null"}) 

; отображаем содержимое нашей коллекции
d coll.$getAll().$toJSON()    

; выбираем один объект, где b is null и отображаем его (здесь вместо JSON Path Language можно использовать "обычный" SQL)
s rset=coll.$queryCollection(
        {"columns":[{"column":"b","path":"$.b"}],
         "restriction":"b is null",
         "limit":1})
w !!,"1)",!,rset.$toJSON()

; открываем объект c documentID=2 и отображаем его
s obj=coll.$get(2)
w !!,"2) ",obj.$toJSON(),!!

; меняем объект (можем добавить новые поля или удалить уже существующие)
s obj."новое поле 1"="новое значение 1"
d obj.$remove("id")

; обновляем его в БД
d coll.$replace(2,obj)
; отображаем текущее состояние нашей БД
d coll.$getAll().$toJSON()    

USER>d ^test
[
{"documentID":1,"documentVersion":1,"content":{"id":1,"поле 1":"значение 1","a":true,"b":null}},
{"documentID":2,"documentVersion":2,"content":{"id":1,"a":false,"b":"null","поле 2":"значение 2"}}
]
 
1)
[
{"_sourceID":1,"_sourceVersion":1,"content":{"id":1,"поле 1":"значение 1","a":true,"b":null}}
]
 
2) {"id":1,"a":false,"b":"null","поле 2":"значение 2"}
 
[
{"documentID":1,"documentVersion":1,"content":{"id":1,"поле 1":"значение 1","a":true,"b":null}},
{"documentID":2,"documentVersion":3,"content":{"a":false,"b":"null","поле 2":"значение 2","новое поле 1":"новое значение 1"}}
]
...
Рейтинг: 0 / 0
11.07.2016, 13:48
    #39271760
Timur Safin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
servit,

Тут такое дело.

Всё опять будет переделано, все системные методы выброшены и переименованные в обычные % методы (с "правильным", уже привычным соглашением об именах).

Ну т.е. не $push, а %Push, не $new а %New, не $getCollection а %GetCollection. Более подробные детали этой переделки будут сообщены дополнительно (в community).
...
Рейтинг: 0 / 0
11.07.2016, 14:46
    #39271809
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Timur SafinВсё опять будет переделаноЭто нормально для FieldTest. Более того, я думаю - не последняя. Главное, что функционал останется.
...
Рейтинг: 0 / 0
11.07.2016, 14:58
    #39271818
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
servitTimur SafinВсё опять будет переделаноЭто нормально для FieldTest. Более того, я думаю - не последняя. Главное, что функционал останется.Одна версия уже успела уйти в релиз, так что это уже может быть проблемой, у меня уже один проект в продакшене с $
...
Рейтинг: 0 / 0
11.07.2016, 15:46
    #39271844
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
DAiMorОдна версия уже успела уйти в релиз, так что это уже может быть проблемой, у меня уже один проект в продакшене с $Что касаетсяTimur Safin<..>не $getCollection а %GetCollection<..>, то это DocDM, который пока не в релизе.
А остальные методы можно обернуть в макросы с условной компиляцией, поставив в зависимость текущую версию Caché. eduard93 пошёл именно этим путём .

PS: согласен, нехорошо менять API после релиза. Это тот случай, когда: "Семь раз отмерь, один - отрежь." ("Look before you leap")
...
Рейтинг: 0 / 0
12.07.2016, 12:20
    #39272338
doublefint
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Timur Safin все системные методы выброшены и переименованные в обычные % методы (с "правильным", уже привычным соглашением об именах) Да!!! :)
...
Рейтинг: 0 / 0
13.07.2016, 08:07
    #39272784
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Есть еще момент, который меня смущал (если у меня опять в голове все не перепуталось, и я действительно правильно помню то, работал экспорт в 2014):
Каше объекты, на которые есть ссылки, превращает в дочерний узел JSON. Это не всегда хорошо, так как в некоторых случаях можно высосать через объект полбазы. Можно ограничивать глубину вложенности, но это не то.
На мой взгляд, нужно при выводе ссылок на объекты выводить его ID (если возможно определить), либо вообще регулировать этот вопрос параметрами поля. При разборе JSON тоже полезно уметь понимать и принимать не полную структуру объекта, а его ID.

Что-то в этом направлении делается?
...
Рейтинг: 0 / 0
13.07.2016, 08:38
    #39272792
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Блок А.Н.Каше объекты, на которые есть ссылки, превращает в дочерний узел JSON. Это не всегда хорошо, так как в некоторых случаях можно высосать через объект полбазы. Можно ограничивать глубину вложенности, но это не то.
На мой взгляд, нужно при выводе ссылок на объекты выводить его ID (если возможно определить), либо вообще регулировать этот вопрос параметрами поля. При разборе JSON тоже полезно уметь понимать и принимать не полную структуру объекта, а его ID.

Что-то в этом направлении делается?Обязательно.Пример для 2016.3
Код: plaintext
SAMPLES>w ##class(Sample.Person).%OpenId(101).$toJSON()
{"$CLASSNAME":"Sample.Employee","$REFERENCE":"101","Age":22,"Company":{"$CLASSNAME":"Sample.Company","$REFERENCE":"4"},"DOB":56006,"FavoriteColors":["Red","Black"],"Home":{"City":"Reston","State":"WY","Street":"5572 Ash Avenue","Zip":79167},"Name":"Gore,David B.","Notes":{"$CLASSNAME":"%Stream.GlobalCharacter","content":["David used to work at DynaDyne.com as a(n) Assistant Director"]},"Office":{"City":"Islip","State":"MN","Street":"9434 First Drive","Zip":15857},"Picture":{"$CLASSNAME":"%Stream.GlobalBinary","$ERROR":"Mapping streams to %AbstractObject not currently supported"},"SSN":"118-21-3732","Salary":44260,"Spouse":{"$CLASSNAME":"Sample.Person","$REFERENCE":"16"},"Title":"Developer"}Если что-то в формате не устраивает, всегда можно переопределить пару callback-методов, пример которых также приводился выше ( 19006466 ).
...
Рейтинг: 0 / 0
13.07.2016, 09:37
    #39272805
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
servit,

В формате не устраивает то, что в нем вообще нет ID. Соотвественно, переданный в JSON объект обратно в хранимый не преобразуешь. Если на внешнем уровне еще можно вручную прилепить ID, то на вложенных узлах что делать? Создавать новые объекты? А если это ссылка, например, на запись справочника? Сохранять в нем новую запись или не сохранять ссылку вообще?
Писать костыли на каждый класс при том, что сам механизм ущербен - как-то неправильно.

Ну и как я уже говорил, создание дочернего узла JSON для хранимого объекта, доступного по ссылке, не всегда нужно (и вообще, непонятно, нужно ли)
...
Рейтинг: 0 / 0
13.07.2016, 09:42
    #39272813
Alexey Maslov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Блок А.Н.,

ИМХО, это общая проблема ссылочной целостности при обмене данными. Не побоитесь передавать ссылку на ID записи справочника? А вдруг "на той стороне" ID в базе по какой-то причине другие? Возможно, GUID или какой-то его "предметный" аналог подошёл бы лучше.

PS. Возможно, пишу тривиальные вещи, и я просто неправильно вас понял.
...
Рейтинг: 0 / 0
13.07.2016, 10:01
    #39272830
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Alexey Maslov,

guid тоже может быть id, не вижу проблемы.
...
Рейтинг: 0 / 0
13.07.2016, 10:44
    #39272868
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
Блок А.Н.В формате не устраивает то, что в нем вообще нет ID. Соотвественно, переданный в JSON объект обратно в хранимый не преобразуешь.Действительно, в формате нет ID, но есть его аналог - $REFERENCE, а также $CLASSNAME, поэтому "из коробки" всё есть для преобразования в обе стороны.
Или мы говорим о разных вещах?
...
Рейтинг: 0 / 0
13.07.2016, 12:05
    #39272955
Блок А.Н.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JSON to Object (ID)
servit есть его аналог - $REFERENCEИзвиняюсь, не по глазам.
В предыдущих версиях было вроде бы _id и _classname, поэтому искал что-то подобное.
...
Рейтинг: 0 / 0
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / JSON to Object (ID) / 25 сообщений из 30, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]