Skip to content
This repository was archived by the owner on Dec 16, 2021. It is now read-only.

Commit b67c7b0

Browse files
authored
Cast value which doesn't match to any rules as string (#22)
* force cast as string if a given value doesn't match to any rules * Throw it away to parse integer and double * Add testConvertToDatastoreValue * Modify README * Change default time zone for timestamp
1 parent fcf3e36 commit b67c7b0

File tree

4 files changed

+101
-20
lines changed

4 files changed

+101
-20
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Apache Beam's `DatastoreIO` doesn't allow us to write same key at once.
4646
mvn clean package
4747
4848
# Run bigquery-to-datastore via the compiled JAR file
49-
java -cp $(pwd)/target/bigquery-to-datastore-bundled-0.5.0.jar \
49+
java -cp $(pwd)/target/bigquery-to-datastore-bundled-0.5.1.jar \
5050
com.github.yuiskw.beam.BigQuery2Datastore \
5151
--project=your-gcp-project \
5252
--runner=DataflowRunner \
@@ -71,7 +71,7 @@ mvn clean package
7171
make package
7272
7373
# run
74-
java -cp $(pwd)/target/bigquery-to-datastore-bundled-0.5.0.jar --help
74+
java -cp $(pwd)/target/bigquery-to-datastore-bundled-0.5.1.jar --help
7575
# or
7676
./bin/bigquery-to-datastore --help
7777
```
@@ -80,7 +80,7 @@ java -cp $(pwd)/target/bigquery-to-datastore-bundled-0.5.0.jar --help
8080
We also offers docker images for this project in [yuiskw/bigquery\-to\-datastore \- Docker Hub](https://hub.docker.com/r/yuiskw/bigquery-to-datastore/).
8181
We have several docker images based on Apache Beam versions.
8282
```
83-
docker run yuiskw/bigquery-to-datastore:0.5.0-beam-2.1 --help
83+
docker run yuiskw/bigquery-to-datastore:0.5.1-beam-2.1 --help
8484
```
8585

8686
### How to install it with homebrew

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
<groupId>com.github.yuiskw</groupId>
2424
<artifactId>bigquery-to-datastore</artifactId>
25-
<version>0.5.0</version>
25+
<version>0.5.1</version>
2626

2727
<packaging>jar</packaging>
2828

src/main/java/com/github/yuiskw/beam/TableRow2EntityFn.java

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ else if (value instanceof java.lang.Integer) {
109109
v = Value.newBuilder().setIntegerValue(((Integer) value).intValue())
110110
.setExcludeFromIndexes(isExcluded).build();
111111
}
112-
else if (value instanceof String && parseInteger((String) value) != null) {
113-
Integer integer = parseInteger((String) value);
114-
v = Value.newBuilder().setIntegerValue(integer.intValue())
115-
.setExcludeFromIndexes(isExcluded).build();
116-
}
112+
// else if (value instanceof String && parseInteger((String) value) != null) {
113+
// Integer integer = parseInteger((String) value);
114+
// v = Value.newBuilder().setIntegerValue(integer.intValue())
115+
// .setExcludeFromIndexes(isExcluded).build();
116+
// }
117117
// LONG
118118
else if (value instanceof java.lang.Long) {
119119
v = Value.newBuilder().setIntegerValue((int) ((Long) value).longValue())
@@ -124,6 +124,10 @@ else if (value instanceof java.lang.Double) {
124124
v = Value.newBuilder().setDoubleValue(((Double) value).doubleValue())
125125
.setExcludeFromIndexes(isExcluded).build();
126126
}
127+
// else if (value instanceof String && parseDouble((String) value) != null) {
128+
// v = Value.newBuilder().setDoubleValue(((Double) value).doubleValue())
129+
// .setExcludeFromIndexes(isExcluded).build();
130+
// }
127131
// TIMESTAMP
128132
else if (value instanceof org.joda.time.LocalDateTime) {
129133
Timestamp timestamp = toTimestamp(((LocalDateTime) value).toLocalDate().toDate());
@@ -147,11 +151,6 @@ else if (value instanceof org.joda.time.LocalDate) {
147151
v = Value.newBuilder().setTimestampValue(timestamp)
148152
.setExcludeFromIndexes(isExcluded).build();
149153
}
150-
// STRING
151-
else if (value instanceof String) {
152-
v = Value.newBuilder().setStringValue((String) value)
153-
.setExcludeFromIndexes(isExcluded).build();
154-
}
155154
// RECORD
156155
else if (value instanceof List) {
157156
ArrayValue.Builder arrayValueBuilder = ArrayValue.newBuilder();
@@ -176,6 +175,12 @@ else if (value instanceof Map) {
176175
}
177176
v = Value.newBuilder().setEntityValue(subEntityBuilder.build()).build();
178177
}
178+
// String
179+
// If a given value is not match the above rule, it deals with it as string.
180+
else {
181+
v = Value.newBuilder().setStringValue(value.toString())
182+
.setExcludeFromIndexes(isExcluded).build();
183+
}
179184
return v;
180185
}
181186

@@ -240,17 +245,34 @@ public Key getKey(String name) {
240245
* Parse integer value
241246
*
242247
* @param value String
243-
* @return parsed integer of null if given value is not integer
248+
* @return parsed integer or null if given value is not integer
244249
*/
245250
public static Integer parseInteger(String value) {
246-
Integer integer = null;
251+
Integer parsed = null;
252+
try {
253+
parsed = Integer.valueOf(value);
254+
} catch (NumberFormatException e) {
255+
// Do nothing.
256+
;
257+
}
258+
return parsed;
259+
}
260+
261+
/**
262+
* Parse double value
263+
*
264+
* @param value String
265+
* @return parsed double or null if given value is not double
266+
*/
267+
public static Double parseDouble(String value) {
268+
Double parsed = null;
247269
try {
248-
integer = Integer.valueOf(value);
270+
parsed = Double.valueOf(value);
249271
} catch (NumberFormatException e) {
250272
// Do nothing.
251273
;
252274
}
253-
return integer;
275+
return parsed;
254276
}
255277

256278
/**
@@ -264,7 +286,7 @@ public static Instant parseDate(String value) {
264286
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d")
265287
.withResolverStyle(ResolverStyle.SMART);
266288
java.time.LocalDate localDate = java.time.LocalDate.parse(value, formatter);
267-
instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
289+
instant = localDate.atStartOfDay().atZone(ZoneId.of("UTC")).toInstant();
268290
} catch (DateTimeParseException e) {
269291
// Do nothing.
270292
;
@@ -295,7 +317,7 @@ public static Instant parseTimestamp(String value) {
295317
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern)
296318
.withResolverStyle(ResolverStyle.SMART);
297319
java.time.LocalDateTime localDateTime = java.time.LocalDateTime.parse(value, formatter);
298-
instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
320+
instant = localDateTime.atZone(ZoneId.of("UTC")).toInstant();
299321
return instant;
300322
} catch (DateTimeParseException e) {
301323
// Do nothing.

src/test/java/com/github/yuiskw/beam/TableRow2EntityFnTest.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,65 @@ public void testConvert2() {
9191
}
9292
}
9393

94+
@Test
95+
public void testConvertToDatastoreValue() {
96+
TableRow2EntityFn fn =new TableRow2EntityFn(
97+
projectId, namespace, null, kind, keyColumn, indexedColumns);
98+
99+
Value v = null;
100+
101+
// String
102+
v = fn.convertToDatastoreValue("value", "hello, world");
103+
assertEquals("hello, world", v.getStringValue());
104+
105+
// Integer
106+
v = fn.convertToDatastoreValue("value", 123);
107+
assertEquals(123, v.getIntegerValue());
108+
109+
// Double
110+
v = fn.convertToDatastoreValue("value", 123.456);
111+
assertEquals(123.456, v.getDoubleValue(), 1e-3);
112+
113+
// Timestamp
114+
v = fn.convertToDatastoreValue("value", "2018-01-01 01:23:45");
115+
assertEquals(1514769825, v.getTimestampValue().getSeconds());
116+
117+
// Date
118+
v = fn.convertToDatastoreValue("value", "2018-01-01");
119+
assertEquals(1514764800, v.getTimestampValue().getSeconds());
120+
121+
// Array
122+
v = fn.convertToDatastoreValue("value", Arrays.asList(1, 2, 3));
123+
assertEquals(3, v.getArrayValue().getValuesCount());
124+
125+
// Struct
126+
Map<String, Object> subMap = new HashMap<String, Object>();
127+
subMap.put("int", 123);
128+
subMap.put("array", Arrays.asList(1, 2, 3));
129+
130+
Map<String, Object> map = new HashMap<String, Object>();
131+
map.put("int", 123);
132+
map.put("double", 123.456);
133+
map.put("string", "hello, world");
134+
map.put("timestamp", "2018-01-01 01:23:45");
135+
map.put("date", "2018-01-01");
136+
map.put("array", Arrays.asList(1, 2, 3));
137+
map.put("struct", subMap);
138+
139+
v = fn.convertToDatastoreValue("value", map);
140+
Entity entity = v.getEntityValue();
141+
assertEquals(123, entity.getPropertiesOrThrow("int").getIntegerValue());
142+
assertEquals(123.456, entity.getPropertiesOrThrow("double").getDoubleValue(), 1e-3);
143+
assertEquals("hello, world", entity.getPropertiesOrThrow("string").getStringValue());
144+
assertEquals(1514769825, entity.getPropertiesOrThrow("timestamp").getTimestampValue().getSeconds());
145+
assertEquals(1514764800, entity.getPropertiesOrThrow("date").getTimestampValue().getSeconds());
146+
assertEquals(3, entity.getPropertiesOrThrow("array").getArrayValue().getValuesCount());
147+
148+
Entity subEntity = entity.getPropertiesOrThrow("struct").getEntityValue();
149+
assertEquals(123, subEntity.getPropertiesOrThrow("int").getIntegerValue());
150+
assertEquals(3, subEntity.getPropertiesOrThrow("array").getArrayValue().getValuesCount());
151+
}
152+
94153
@Test
95154
public void testIsDate() {
96155
assertNotNull(TableRow2EntityFn.parseDate("2017-01-01"));

0 commit comments

Comments
 (0)