I have a pubsub topic with an avro schema, a bigquery subscription and a matching bigquery table. To test this I use a python script to publish a number of records.
Published records that have None or no value for the last column appear in bigquery soon after publishing. As soon as a value is specified for the last column, the record does not appear. I changed the column order and it is always the last column, that generates the issue.
How can I fix that?
Avro schema
{
"type": "record",
"name": "incoming_telemetry",
"doc": "Telemetry message from herby device",
"fields": [
{"name": "deviceId", "type": "string"},
{"name": "timestamp", "type": "string"},
{"name": "waterTableRange", "type": ["null", "float"]},
{"name": "batteryCapacity", "type": ["null", "float"]},
{"name": "batteryCurrent", "type": ["null", "float"]},
{"name": "solarVoltage", "type": ["null", "float"]},
{"name": "batteryVoltage", "type": ["null", "float"]},
{"name": "temperature", "type": ["null", "float"]},
{"name": "wifiStrength", "type": ["null", "float"]},
{"name": "flowRate", "type": ["null", "float"]}
]
}
Bigquery schema
[
{
"name": "timestamp",
"type": "TIMESTAMP",
"mode": "REQUIRED"
},
{
"name": "deviceId",
"type": "STRING",
"mode": "REQUIRED"
},
{
"name": "waterTableRange",
"type": "FLOAT",
"mode": "NULLABLE"
},
{
"name": "batteryCapacity",
"type": "FLOAT",
"mode": "NULLABLE"
},
{
"name": "batteryCurrent",
"type": "FLOAT",
"mode": "NULLABLE"
},
{
"name": "solarVoltage",
"type": "FLOAT",
"mode": "NULLABLE"
},
{
"name": "batteryVoltage",
"type": "FLOAT",
"mode": "NULLABLE"
},
{
"name": "temperature",
"type": "FLOAT",
"mode": "NULLABLE"
},
{
"name": "wifiStrength",
"type": "FLOAT",
"mode": "NULLABLE"
},
{
"name": "flowRate",
"type": "FLOAT",
"mode": "NULLABLE"
}
]
python script
import io
from datetime import datetime, timezone
import avro.schema
import google.auth
from avro.io import DatumWriter, BinaryEncoder, BinaryDecoder, DatumReader
from google.cloud import pubsub_v1, bigquery
INCOMING_TOPIC_ID = 'incoming-telemetry-v1.0'
SCHEMA_FILE = '../../schemas/incoming_telemetry_v1.0.avsc'
DATASET_ID = 'telemetry'
TABLE_ID = 'raw-telemetry'
GCP_TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
timestamp = datetime.now(timezone.utc).strftime(GCP_TIMESTAMP_FORMAT)
records = [
{
'deviceId': '1',
'timestamp': timestamp,
'waterTableRange': None,
'batteryCapacity': None,
'batteryCurrent': None,
'solarVoltage': None,
'batteryVoltage': None,
'temperature': None,
'wifiStrength': None,
'flowRate': None,
},
{
'deviceId': '2',
'timestamp': timestamp,
},
{
'deviceId': '3',
'timestamp': timestamp,
'waterTableRange': 1.1,
'batteryCapacity': 2.2,
'batteryCurrent': 3.3,
'solarVoltage': 4.4,
'batteryVoltage': 5.5,
'temperature': 6.6,
'wifiStrength': 7.7,
'flowRate': None,
},
{
'deviceId': '4',
'timestamp': timestamp,
'wifiStrength': 7.7,
},
{
'deviceId': '5',
'timestamp': timestamp,
'waterTableRange': 1.1,
'batteryCapacity': 2.2,
'batteryCurrent': 3.3,
'solarVoltage': 4.4,
'batteryVoltage': 5.5,
'temperature': 6.6,
'wifiStrength': 7.7,
'flowRate': 8.8,
},
{
'deviceId': '6',
'timestamp': timestamp,
'flowRate': 8.8,
},
]
project_id = google.auth.default()[1]
publisher_client = pubsub_v1.PublisherClient()
topic_path = publisher_client.topic_path(project_id, INCOMING_TOPIC_ID)
file = open(SCHEMA_FILE, 'rb')
schema = avro.schema.parse(file.read())
writer = DatumWriter(schema)
for record in records:
byte_stream = io.BytesIO()
encoder = BinaryEncoder(byte_stream)
writer.write(record, encoder)
data = byte_stream.getvalue()
byte_stream.flush()
future = publisher_client.publish(topic_path, data)
print(f"Published message ID: {future.result()}")
records 1-4 appear while records 5 + 6 are nowhere.
