datastore를 사용해 보았을 때
소개
GAE/Go 1학년입니다. API 서버의 코드를 작성하는 중 빠진 것을
정리하려고 생각합니다.
이번에는 datastore입니다.
트랜잭션 기능의 사용법도 기억해 쾌적해져 온 요즘입니다.
※GAE/Go 전제의 쓰는 방법이 되어 버리는 것, 용서해 주세요.
string 속성은 기본적으로 1500byte까지만 저장할 수 있습니다.
올해 처음에 빠진 것이 이것이었습니다.
datastore에서는 struct가 그대로 schema가 되기 때문에, 어쩐지 string의 상한을 의식하지 않았던 것이 좋지 않았습니다.
다음은 문서입니다. (필자가 GAE/Go를 사용하고 있기 때문에 Go보다
Fields (except for []byte) are indexed by default. Strings longer than 1500 bytes cannot be indexed; fields used to store long strings should be tagged with "noindex". Similarly, ByteStrings longer than 1500 bytes cannot be indexed.
견적 출처: htps : // c ぉ d. 오, ぇ. 코 m / 아펜 기네 / 드 cs / 고 / 다타 s / 루후 렌세 # hdr-P 로페 치에 s
noindex 태그를 붙이면 저장할 수 있습니다.
설명문이나 블로그라든지, 장문을 DB에 보관 유지하고 싶을 때에는 필수군요.
GAE/Go만 IN구를 사용할 수 없다
여러 Key를 사용하여 Get 할 수는 있지만 특정 속성 값으로 SELECT * FROM TABLE WHERE Property IN (A, B, C)
같은 Query를 던질 수는 없습니다.
하지만 Java라고 할 수있는 것 같습니다.
Go 문서라면
Operator Meaning
= Equal to
< Less than
<= Less than or equal to
> Greater than
>= Greater than or equal to
견적 출처: htps : // c ぉ d. 오, ぇ. 코 m / 아펜 기네 / 도 cs / 고 / 타타 s 토레 / 쿠에 리에 s # 후 리 rs
하지만 Java이면
Operator Meaning
EQUAL Equal to
LESS_THAN Less than
LESS_THAN_OR_EQUAL Less than or equal to
GREATER_THAN Greater than
GREATER_THAN_OR_EQUAL Greater than or equal to
NOT_EQUAL Not equal to
IN Member of (equal to any of the values in a specified list)
견적 출처: htps : // c ぉ d. 오, ぇ. 코 m / 아펜 기네 / 도 cs / 그럼 ぁ / data s 토레 / 쿠에 리 s # 푹신 rs
되어 있고, IN이 있습니다
Transaction 기능을 사용하고 싶지 않습니다.
다음과 같은 코드를 작성했습니다.
type (
SampleRepository struct {
c context.Context
}
Sample struct {
ID int `datastore:"Id"`
Count int `datastore:"Count"`
}
)
func (r *SampleRepository) Save(sample *Sample) error {
key := datastore.NewKey(r.c, "Sample", "", sample.ID, nil)
if _, err := datastore.Put(ctx, key, sample); err != nil {
return err
}
return nil
}
func handle(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
sr := SampleRepository{c: ctx}
s := Sample{ID: 1}
err := datastore.RunInTransaction(ctx, func(ctx context.Context) error {
s.Count++
return sr.Save(s)
}, nil)
if err != nil {
//エラーレスポンスを返す
return
}
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
fmt.Fprintf(w, "Count=%d", s.Count)
}
func(ctx context.Context) error
인수는 transaction을 포함하는 컨텍스트를 지정합니다.
transaction을 내장한 context가 아니면 트랜잭션은 당연히 효과가 없었습니다.
(참고: htps: //아이 c. 오 rg/오오 gぇ. 미안해. 오 rg / 아펜 기네 / r r l # 룬 T 란사 c 치오 노세 )
Repository 구조체를 만들 때 속성으로 context를 투입하도록 했기 때문에,
문제를 깨닫는 데 시간이 걸렸습니다.
결론
그 밖에도, schema 변경해 마이그레이션 하는 것이 힘들거나 , 라고 하는 고생도 있습니다만 , MySQL 때에 당연히 하고 있던 sharding 을 생각하지 않아도 좋아지거나 ,
칼럼 추가는 간단하거나, 좋은 곳도 가득 있구나, 라는 감상입니다.
아직 Ancestor Query를 사용할 수 없으므로 어딘가에서 도전하고 싶습니다.
Reference
이 문제에 관하여(datastore를 사용해 보았을 때), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yagitatsu/items/1655dcfb9a1c7bf42b5e
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
올해 처음에 빠진 것이 이것이었습니다.
datastore에서는 struct가 그대로 schema가 되기 때문에, 어쩐지 string의 상한을 의식하지 않았던 것이 좋지 않았습니다.
다음은 문서입니다. (필자가 GAE/Go를 사용하고 있기 때문에 Go보다
Fields (except for []byte) are indexed by default. Strings longer than 1500 bytes cannot be indexed; fields used to store long strings should be tagged with "noindex". Similarly, ByteStrings longer than 1500 bytes cannot be indexed.
견적 출처: htps : // c ぉ d. 오, ぇ. 코 m / 아펜 기네 / 드 cs / 고 / 다타 s / 루후 렌세 # hdr-P 로페 치에 s
noindex 태그를 붙이면 저장할 수 있습니다.
설명문이나 블로그라든지, 장문을 DB에 보관 유지하고 싶을 때에는 필수군요.
GAE/Go만 IN구를 사용할 수 없다
여러 Key를 사용하여 Get 할 수는 있지만 특정 속성 값으로 SELECT * FROM TABLE WHERE Property IN (A, B, C)
같은 Query를 던질 수는 없습니다.
하지만 Java라고 할 수있는 것 같습니다.
Go 문서라면
Operator Meaning
= Equal to
< Less than
<= Less than or equal to
> Greater than
>= Greater than or equal to
견적 출처: htps : // c ぉ d. 오, ぇ. 코 m / 아펜 기네 / 도 cs / 고 / 타타 s 토레 / 쿠에 리에 s # 후 리 rs
하지만 Java이면
Operator Meaning
EQUAL Equal to
LESS_THAN Less than
LESS_THAN_OR_EQUAL Less than or equal to
GREATER_THAN Greater than
GREATER_THAN_OR_EQUAL Greater than or equal to
NOT_EQUAL Not equal to
IN Member of (equal to any of the values in a specified list)
견적 출처: htps : // c ぉ d. 오, ぇ. 코 m / 아펜 기네 / 도 cs / 그럼 ぁ / data s 토레 / 쿠에 리 s # 푹신 rs
되어 있고, IN이 있습니다
Transaction 기능을 사용하고 싶지 않습니다.
다음과 같은 코드를 작성했습니다.
type (
SampleRepository struct {
c context.Context
}
Sample struct {
ID int `datastore:"Id"`
Count int `datastore:"Count"`
}
)
func (r *SampleRepository) Save(sample *Sample) error {
key := datastore.NewKey(r.c, "Sample", "", sample.ID, nil)
if _, err := datastore.Put(ctx, key, sample); err != nil {
return err
}
return nil
}
func handle(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
sr := SampleRepository{c: ctx}
s := Sample{ID: 1}
err := datastore.RunInTransaction(ctx, func(ctx context.Context) error {
s.Count++
return sr.Save(s)
}, nil)
if err != nil {
//エラーレスポンスを返す
return
}
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
fmt.Fprintf(w, "Count=%d", s.Count)
}
func(ctx context.Context) error
인수는 transaction을 포함하는 컨텍스트를 지정합니다.
transaction을 내장한 context가 아니면 트랜잭션은 당연히 효과가 없었습니다.
(참고: htps: //아이 c. 오 rg/오오 gぇ. 미안해. 오 rg / 아펜 기네 / r r l # 룬 T 란사 c 치오 노세 )
Repository 구조체를 만들 때 속성으로 context를 투입하도록 했기 때문에,
문제를 깨닫는 데 시간이 걸렸습니다.
결론
그 밖에도, schema 변경해 마이그레이션 하는 것이 힘들거나 , 라고 하는 고생도 있습니다만 , MySQL 때에 당연히 하고 있던 sharding 을 생각하지 않아도 좋아지거나 ,
칼럼 추가는 간단하거나, 좋은 곳도 가득 있구나, 라는 감상입니다.
아직 Ancestor Query를 사용할 수 없으므로 어딘가에서 도전하고 싶습니다.
Reference
이 문제에 관하여(datastore를 사용해 보았을 때), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yagitatsu/items/1655dcfb9a1c7bf42b5e
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Operator Meaning
= Equal to
< Less than
<= Less than or equal to
> Greater than
>= Greater than or equal to
Operator Meaning
EQUAL Equal to
LESS_THAN Less than
LESS_THAN_OR_EQUAL Less than or equal to
GREATER_THAN Greater than
GREATER_THAN_OR_EQUAL Greater than or equal to
NOT_EQUAL Not equal to
IN Member of (equal to any of the values in a specified list)
다음과 같은 코드를 작성했습니다.
type (
SampleRepository struct {
c context.Context
}
Sample struct {
ID int `datastore:"Id"`
Count int `datastore:"Count"`
}
)
func (r *SampleRepository) Save(sample *Sample) error {
key := datastore.NewKey(r.c, "Sample", "", sample.ID, nil)
if _, err := datastore.Put(ctx, key, sample); err != nil {
return err
}
return nil
}
func handle(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
sr := SampleRepository{c: ctx}
s := Sample{ID: 1}
err := datastore.RunInTransaction(ctx, func(ctx context.Context) error {
s.Count++
return sr.Save(s)
}, nil)
if err != nil {
//エラーレスポンスを返す
return
}
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
fmt.Fprintf(w, "Count=%d", s.Count)
}
func(ctx context.Context) error
인수는 transaction을 포함하는 컨텍스트를 지정합니다.transaction을 내장한 context가 아니면 트랜잭션은 당연히 효과가 없었습니다.
(참고: htps: //아이 c. 오 rg/오오 gぇ. 미안해. 오 rg / 아펜 기네 / r r l # 룬 T 란사 c 치오 노세 )
Repository 구조체를 만들 때 속성으로 context를 투입하도록 했기 때문에,
문제를 깨닫는 데 시간이 걸렸습니다.
결론
그 밖에도, schema 변경해 마이그레이션 하는 것이 힘들거나 , 라고 하는 고생도 있습니다만 , MySQL 때에 당연히 하고 있던 sharding 을 생각하지 않아도 좋아지거나 ,
칼럼 추가는 간단하거나, 좋은 곳도 가득 있구나, 라는 감상입니다.
아직 Ancestor Query를 사용할 수 없으므로 어딘가에서 도전하고 싶습니다.
Reference
이 문제에 관하여(datastore를 사용해 보았을 때), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yagitatsu/items/1655dcfb9a1c7bf42b5e
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(datastore를 사용해 보았을 때), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yagitatsu/items/1655dcfb9a1c7bf42b5e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)