omnata-plugin-runtime 0.4.7a104__tar.gz → 0.4.8a105__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/PKG-INFO +1 -1
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/pyproject.toml +1 -1
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/omnata_plugin.py +56 -43
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/LICENSE +0 -0
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/README.md +0 -0
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/__init__.py +0 -0
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/api.py +0 -0
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/configuration.py +0 -0
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/forms.py +0 -0
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/logging.py +0 -0
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/plugin_entrypoints.py +0 -0
- {omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/rate_limiting.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "omnata-plugin-runtime"
|
3
|
-
version = "0.4.
|
3
|
+
version = "0.4.8-a105"
|
4
4
|
description = "Classes and common runtime components for building and running Omnata Plugins"
|
5
5
|
authors = ["James Weakley <james.weakley@omnata.com>"]
|
6
6
|
readme = "README.md"
|
@@ -1244,55 +1244,68 @@ class InboundSyncRequest(SyncRequest):
|
|
1244
1244
|
)
|
1245
1245
|
primary_key_field = None
|
1246
1246
|
records = results_df.to_dict("records")
|
1247
|
-
|
1248
|
-
|
1247
|
+
# this extra bit of source_defined_primary_key logic is just to catch the situation where the plugin accidentally
|
1248
|
+
# provides an empty list as the source defined primary key (SFMC plugin did this for a while, so some customers have [] here).
|
1249
|
+
# This should be caught upstream during configuration, but we'll check here too.
|
1250
|
+
# Note that source defined primary keys override any user choice.
|
1251
|
+
primary_key_correctly_defined_by_source = False
|
1252
|
+
if stream_obj.source_defined_primary_key is not None:
|
1253
|
+
if isinstance(stream_obj.source_defined_primary_key,list):
|
1254
|
+
if len(stream_obj.source_defined_primary_key)>0:
|
1255
|
+
primary_key_correctly_defined_by_source = True
|
1256
|
+
else:
|
1257
|
+
primary_key_correctly_defined_by_source = True
|
1258
|
+
|
1259
|
+
if primary_key_correctly_defined_by_source:
|
1260
|
+
primary_key_field = stream_obj.source_defined_primary_key
|
1249
1261
|
elif self._streams_dict[stream_name].primary_key_field is not None:
|
1250
1262
|
primary_key_field = self._streams_dict[stream_name].primary_key_field
|
1251
1263
|
else:
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
f"Primary key field '{primary_key_field}' was not present in all records for stream {stream_name}"
|
1290
|
-
)
|
1291
|
-
else:
|
1264
|
+
# originally, we did not require primary keys for inbound syncs if they were doing the replace option
|
1265
|
+
# when we brought in delete flagging, we began to mandate that primary keys are defined
|
1266
|
+
raise ValueError(f"Stream {stream_name} does not have a primary key field defined")
|
1267
|
+
if isinstance(primary_key_field,list) and len(primary_key_field) == 1:
|
1268
|
+
# don't hash it if it's just a single value
|
1269
|
+
primary_key_field = primary_key_field[0]
|
1270
|
+
if isinstance(primary_key_field,list):
|
1271
|
+
primary_key_fields = cast(List[str],primary_key_field)
|
1272
|
+
primary_key_fields = sorted(primary_key_fields)
|
1273
|
+
# handle the sitation where the primary key is a list of fields
|
1274
|
+
# first, check that all records contain all of the primary key fields
|
1275
|
+
if not all(
|
1276
|
+
all(
|
1277
|
+
field in record["RECORD_DATA"]
|
1278
|
+
for field in primary_key_fields
|
1279
|
+
)
|
1280
|
+
for record in records
|
1281
|
+
):
|
1282
|
+
raise ValueError(
|
1283
|
+
f"Primary key fields '{primary_key_fields}' were not present in all records for stream {stream_name}"
|
1284
|
+
)
|
1285
|
+
# hash all of the primary key fields
|
1286
|
+
results_df["APP_IDENTIFIER"] = results_df["RECORD_DATA"].apply(lambda x: self.get_hash([str(x[field]) for field in primary_key_fields]))
|
1287
|
+
else:
|
1288
|
+
# the primary key field could contain a nested field, so we need to check for that
|
1289
|
+
# we need to check that each record in the results contains the primary key field
|
1290
|
+
if not all(
|
1291
|
+
primary_key_field in record["RECORD_DATA"]
|
1292
|
+
for record in records
|
1293
|
+
):
|
1294
|
+
if "." in primary_key_field:
|
1295
|
+
primary_key_field = primary_key_field.split(".")
|
1296
|
+
|
1297
|
+
if not all(
|
1298
|
+
get_nested_value(record["RECORD_DATA"], primary_key_field)
|
1299
|
+
for record in records
|
1300
|
+
):
|
1292
1301
|
raise ValueError(
|
1293
1302
|
f"Primary key field '{primary_key_field}' was not present in all records for stream {stream_name}"
|
1294
1303
|
)
|
1295
|
-
|
1304
|
+
else:
|
1305
|
+
raise ValueError(
|
1306
|
+
f"Primary key field '{primary_key_field}' was not present in all records for stream {stream_name}"
|
1307
|
+
)
|
1308
|
+
results_df["APP_IDENTIFIER"] = results_df["RECORD_DATA"].apply(lambda x: get_nested_value(dict(x),primary_key_field))
|
1296
1309
|
# ensure APP_IDENTIFIER is a string
|
1297
1310
|
results_df["APP_IDENTIFIER"] = results_df["APP_IDENTIFIER"].apply(str)
|
1298
1311
|
# the timestamps in Snowflake are TIMESTAMP_LTZ, so we upload in string format to ensure the
|
File without changes
|
File without changes
|
File without changes
|
{omnata_plugin_runtime-0.4.7a104 → omnata_plugin_runtime-0.4.8a105}/src/omnata_plugin_runtime/api.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|