# Insert data in a custom table with the S&F protection

**URL:** <https://forum.inductiveautomation.com/t/insert-data-in-a-custom-table-with-the-s-f-protection/110935>\
**Category:** Module Development\
**Tags:** ignition83\
**Created:** [September 24, 2025, 6:30pm UTC](https://forum.inductiveautomation.com/t/insert-data-in-a-custom-table-with-the-s-f-protection/110935 "2025-09-24T18:30:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [September 24, 2025, 6:30pm UTC](https://forum.inductiveautomation.com/t/insert-data-in-a-custom-table-with-the-s-f-protection/110935/1 "2025-09-24T18:30:41Z")

</div>

According to the doc:

### Store and Forward Connection Policy

Database connections by default have a pool of eight connections. The Store and Forward engine is multi-threaded, meaning the engine can take advantage of more than one of these connections at a time. This also means that if the Store and Forward engine is storing a particular type of data, such as tag history, that action will not block the engine from concurrently storing a different type of data, such as Alarm Journal or Audit Profile data.

There are **six different types of data** that can be stored and forwarded, meaning up to six of your available connections can be used at the same time. Each available data type is listed below:

- Alarming
- Auditing
- **Scripting**
- SECS/GEM
- Tag history
- Transaction Group

I suppose that my module use case is similar to **scripting** feature  
available with **system.db.runSFPrepUpdate(query, args, datasources)**  
as I need to **insert data in a custom table with the S&F protection**

if someone can share the type of persistent data to use or an example ?

I don't find a "scripting" or something to type to deal with custom table in **PersistentData**?

> **[PersistentData](https://files.inductiveautomation.com/sdk/javadoc/ignition83/8.3.0/com/inductiveautomation/ignition/gateway/storeforward/data/PersistentData.html)**
>
> declaration: package: com.inductiveautomation.ignition.gateway.storeforward.data, interface: PersistentData

Perhaps we have to use **AbstractDatasourceSink**?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [September 24, 2025, 10:04pm UTC](https://forum.inductiveautomation.com/t/insert-data-in-a-custom-table-with-the-s-f-protection/110935/2 "2025-09-24T22:04:50Z")

</div>

The data that's ultimately passed in to the rest of the system is an instance of `com.inductiveautomation.ignition.gateway.datasource.storage.QuerySFData`.  
The `StorageKey` is created with the `com.inductiveautomation.ignition.gateway.storeforward.StorageKey.repeated` factory using the database connection name.

```python
        var manager = context.getStoreAndForwardManager();
        for (StorageKey storageKey : storageKeys) {
            try {
                manager.storeData(storageKey, new QuerySFData(query, values, storageKey.engineId()));

```

---

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [September 25, 2025, 5:17am UTC](https://forum.inductiveautomation.com/t/insert-data-in-a-custom-table-with-the-s-f-protection/110935/3 "2025-09-25T05:17:47Z")

</div>

> [@paul-griffith](#):
>
> `QuerySFData`

it seems that **QuerySFData** is an internal class not available in the SDK...

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [September 25, 2025, 3:46pm UTC](https://forum.inductiveautomation.com/t/insert-data-in-a-custom-table-with-the-s-f-protection/110935/4 "2025-09-25T15:46:31Z")

</div>

Ah, yeah, it sure is. I was going to recommend you stand up your own similar class, but there's some complications if you're dealing with arbitrary objects as query parameters that you need to serialize, and I don't know how the experience of doing that as an external user will go...

I'll see if I can get someone with S+F experience to chime in on a 'recommended' path here.

---

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [September 25, 2025, 4:45pm UTC](https://forum.inductiveautomation.com/t/insert-data-in-a-custom-table-with-the-s-f-protection/110935/5 "2025-09-25T16:45:03Z")

</div>

Thanks !  
For my use case, I've found a workaround. I will put some code outside the module in order to script using **system.db.runSFPrepUpdate**.  
Another way is perhaps to invoke the scriptManager and the system.db.runSFPrepUpdate but it's a bit anti-pattern for a module.
