Inputting data one row at a time instead of all at once in groups

I am working on a project to extract rows from a large JSON document and insert them into an SQL Server database.

The current code I have successfully inserts one row at a time into the table, which seems to be every 1000th row.

add-type -path "C:\Program Files\WindowsPowerShell\Modules\newtonsoft.json\1.0.2.201\libs\newtonsoft.json.dll"
install-module sqlserver -AllowClobber

class EliteCoords {
    [double] $x
    [double] $y
    [double] $z
}

class EliteSystem {
    [int]         $id
    [long]        $id64
    [string]      $name
    [EliteCoords] $coords
    [string]      $date 
}

$dt = New-Object system.data.datatable

$dt.Columns.Add("ID",[int])
$dt.Columns.Add("ID64",[long])
$dt.Columns.Add("Name",[string])
$dt.Columns.Add("Coordsx",[decimal])
$dt.Columns.Add("Coordsy",[decimal])
$dt.Columns.Add("Coordsz",[decimal])
$dt.Columns.Add("DiscoveryDate",[string])

$stream = (Get-Item c:\code\systemsWithCoordinates.json).OpenText()
$reader = [Newtonsoft.Json.JsonTextReader]::new($stream)
while ($reader.Read()) {
    $cnt = 0
    $dt.Clear()
    while ($cnt -le 1000) {
        $cnt = $cnt + 1

        if ($reader.TokenType -eq 'StartObject') {

            $row = [Newtonsoft.Json.JsonSerializer]::CreateDefault().Deserialize($reader, [EliteSystem])

            $dr = $dt.NewRow()

            $dr["ID"]            = $row.id
            $dr["ID64"]          = $row.id64
            $dr["Name"]          = $row.name
            $dr["Coordsx"]       = $row.coords.x
            $dr["Coordsy"]       = $row.coords.y
            $dr["Coordsz"]       = $row.coords.z
            $dr["DiscoveryDate"] = $row.date

            $dt.Rows.Add($dr)       
        }
    }

    write-sqltabledata -ServerInstance ELITEDANGEROUS -Database EDSM -Schema Staging -Table SystemsWithCoordinates -InputData $dt
}

$stream.Close()

I have identified that the issue lies in skipping the if block for all iterations except the first within the inner while loop due to changes in token type from StartObject to StartArray.

Attempts to resolve this include adding another reader loop inside, but it ends up reading the entire file or simply reading the array instead of object, which fails due to nested JSON structure.

To batch process and handle 1000 rows effectively, what would be the optimal way to structure the loops?

Answer №1

Your issue arises from the fact that you are clearing and flushing the table every time $reader.Read() is called, which means for each row.

Instead, it would be more efficient to accumulate rows until reaching 1000, then flush:

$stream = (Get-Item c:\code\systemsWithCoordinates.json).OpenText()
$reader = [Newtonsoft.Json.JsonTextReader]::new($stream)
try {
    $serializer = [Newtonsoft.Json.JsonSerializer]::CreateDefault()
    while ($reader.Read()) {
        # Accumulate a row if at the start of an object.
        if ($reader.TokenType -eq 'StartObject') {                
            $row = serializer.Deserialize($reader, [EliteSystem])

            $dr = $dt.NewRow()

            $dr["ID"]            = $row.id
            $dr["ID64"]          = $row.id64
            $dr["Name"]          = $row.name
            $dr["Coordsx"]       = $row.coords.x
            $dr["Coordsy"]       = $row.coords.y
            $dr["Coordsz"]       = $row.coords.z
            $dr["DiscoveryDate"] = $row.date

            $dt.Rows.Add($dr)       
        }

        # Flush 1000 accumulated rows.
        if ($dt.Rows.Count -ge 1000) {
            write-sqltabledata -ServerInstance ELITEDANGEROUS -Database EDSM -Schema Staging -Table SystemsWithCoordinates -InputData $dt
            $dt.Clear()
        }
    }

    # Flush any remaining rows.
    if ($dt.Rows.Count -ge 0) {
        write-sqltabledata -ServerInstance ELITEDANGEROUS -Database EDSM -Schema Staging -Table SystemsWithCoordinates -InputData $dt
        $dt.Clear()
    }
}
finally {
    $reader.Close()
    $stream.Close()
}

Points to consider:

  • Consider disposing of the StreamReader and JsonTextReader in a finally block, especially in case of exceptions. For guidance on this, check out How to implement using statement in powershell?.

  • Allocating the serializer only once can enhance performance with no added cost.

  • Without seeing your JSON file, it's hard to determine if there could be further issues with the EliteSystem data model used for each row. If the JSON file is a jagged 2d array, adjustments might be necessary.

Answer №2

To solve the issue, it was suggested to replace the inner loop with a break statement. Additionally, an outer loop should be added, which will continue until the End of Stream marker is reached.

add-type -path "C:\Program Files\WindowsPowerShell\Modules\newtonsoft.json\1.0.2.201\libs\newtonsoft.json.dll"
#install-module sqlserver -AllowClobber

class EliteCoords {
    [double] $x
    [double] $y
    [double] $z
}

class EliteSystem {
    [int]         $id
    [long]        $id64
    [string]      $name
    [EliteCoords] $coords
    [string]      $date 
}

$dt = New-Object system.data.datatable

$dt.Columns.Add("ID",[int])
$dt.Columns.Add("ID64",[long])
$dt.Columns.Add("Name",[string])
$dt.Columns.Add("Coordsx",[decimal])
$dt.Columns.Add("Coordsy",[decimal])
$dt.Columns.Add("Coordsz",[decimal])
$dt.Columns.Add("DiscoveryDate",[string])

$stream = (Get-Item c:\code\systemsWithCoordinates.json).OpenText()
$reader = [Newtonsoft.Json.JsonTextReader]::new($stream)
while ($stream.EndOfStream -eq $false) {
$cnt = 0
    $dt.Clear()
    while ($reader.Read()) {

        if ($reader.TokenType -eq 'StartObject') {

                $row = [Newtonsoft.Json.JsonSerializer]::CreateDefault().Deserialize($reader, [EliteSystem])

                $dr = $dt.NewRow()

                $dr["ID"]            = $row.id
                $dr["ID64"]          = $row.id64
                $dr["Name"]          = $row.name
                $dr["Coordsx"]       = $row.coords.x
                $dr["Coordsy"]       = $row.coords.y
                $dr["Coordsz"]       = $row.coords.z
                $dr["DiscoveryDate"] = $row.date

                $dt.Rows.Add($dr)       


        $cnt = $cnt + 1


        }
        if ($cnt -gt 9999) {break}
    }
    write-sqltabledata -ServerInstance ELITEDANGEROUS -Database EDSM -Schema Staging -Table SystemsWithCoordinates -InputData $dt -Timeout 0
}

$stream.Close()

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating the necessary JSON structure in iOS: A step-by-step guide

Here is the JSON response I received: { "projects": [ { "id": 8, "name": "Andriod APP", "identifier": "andriod-app", "description": "", "status": 1, "is_public": true, "created_on": "2015-06-29T11:54:23Z", "updated_on": "2015-06-29T11:54:23Z" }, ], "total ...

IOS JSON Response Data

I am looking for guidance on how to parse a JSON response within a tableview cell. Can someone provide me with the code? ...

Converting JSON to XML in Java while preserving attributes

When utilizing the org.json json library, converting from XML to JSON is straightforward. However, the conversion back to XML results in JSON attributes being converted into XML nodes: import org.json.JSONObject; import org.json.XML; public class Test { ...

Expand the grid with extra rows once it has been generated, especially when dealing with a large volume of database records, utilizing JQGrid or JSGrid

Having a large dataset (json) that takes too long to display in the grid for users, I'm looking for a solution. My idea is to initially run a filtered query (e.g. records from the current year) to quickly build the grid. Once the grid is presented to ...

Issue with using Javascript variables within Highcharts

I am facing an issue with displaying a high charts pie chart dynamically. When I pass the exact value format into the data index in the high chart, it doesn't show anything in the chart. However, if I directly assign a value to a variable, it works fi ...

Tips on retrieving information from a Json data structure

I've been attempting for quite some time to extract data from a Json local file. Currently, my code looks like this: static Future<String> loadJsonData() async { var jsonText = await rootBundle.loadString('assets/Json/CDV.json'); ...

What is the best method for presenting nested JSON data in React using a key-value pair format?

This component serves as the product description section with tabs for both description and details. Selecting the description tab displays the product specifications in a tabular format. We are utilizing the Axios library to fetch JSON data from an API. I ...

Is it possible to manipulate JSON data using Python in conjunction with the AWS List Pricing API?

I am trying to filter out the JSON data where the operating system is Linux, but I'm facing some difficulties. Here is a snippet of the JSON: '' : { I'm unsure of how this section should be represented in a dictionary: "DQ578CGN99KG ...

Ways to eliminate different types of Keys from JSON

Here is a snippet of the JSON data I am working with: { "expressions": { "storyId": "doesNotMatter" }, "facts": { } } I need to figure out how to remove the 'storyId' key from this JSON by converting it into a string and using Regex. Can an ...

Serializing and deserializing Tuples with Jackson in Scala using JSON

Here, I am attempting to perform a round-trip operation on a Tuple2 using the jackson-module-scala library in Scala 2.10.4. However, it seems that the serializer encodes the Tuple2 as a JSON array, leading to issues with deserialization. Why does this ha ...

Append a new object of a class to a collection

Within my codebase, I've defined a class called Email within a class library to store values collected from textboxes in the UI. The snippet of code is structured as follows: namespace MessageLibrary { public class Email { private int ...

Using Powershell to Generate a Simple JSON Document

I'm new to working with JSON and could use some assistance in creating a basic JSON file. Here is the code I have so far: $fruits = lookup-fruit | ConvertFrom-Json foreach ($fruit in $fruits) { $fruit.name $fruit.color $fruit.origin } My goa ...

Mapping a JSON array within a static method in Angular2 and TypeScript

Struggling with the syntax to properly map my incoming data in a static method. The structure of my json Array is as follows: [ { "documents": [ { "title": "+1 (film)", "is-saved": false, ...

Extracting JSON data from an HTML page using identical field names

I am encountering a problem with scraping a page and extracting JSON from it. The <script type="text/x-magento-init"> tag contains the JSON data that I am attempting to retrieve. However, when using .find('script',{'type&apos ...

Exploring the capabilities of JQuery UI tabs' beforeLoad feature using JSON data

Trying to dynamically load content of a tab using an ASP.NET method decorated with the [WebMethod] attribute. [WebMethod] public static string Result() { return RenderControl("WebUserControl1.ascx"); } It functions correctly when the tab is loaded wit ...

What is the method for using findOne() in mongoose to retrieve a subset of an array of documents that meet specific criteria?

My query results in the following output: const pendingOfThisShop = await ShopProfile.findOne({ shop: req.shop.id, "shopsAffiliate.status":"pending" },{ shopsAffiliate: 1, _id: 0 } The returned object looks like this: { "shopsAffiliate": [ { ...

What is the best way to import my json information into an HTML table and customize the rows as radio buttons using only Javascript?

I am facing an issue with processing a JSON response: var jsondata = dojo.fromJson(response); There is also a string that I am working with: var jsonString = jsondata.items; The variable jsonString represents the JSON data in the file: jsonString="[ ...

What is the process for parsing JSON data in a Django application?

How can I extract data from a JSON object transmitted by an android form (using the GET method) to a django python server? I have attempted this approach def post_article(sample): #sample represents the HTTP request json_data = sample.read() ...

Populate Chart.js with a specific set of JSON data

As I delve into the world of JavaScript, I'm faced with a challenging issue that I need help resolving: I have a JSON file housing an array of data. What I aim to do is extract specific arrays from the month of August (Reports, Average, Global) and d ...

Using JSON to pass a dynamic array to Morris Chart

My task involves creating a graph using Morris Charts with a dynamic rectangular array. The array consists of a variable number of columns and looks like this: To achieve this, I attempted to pass the data to Morris Charts using JSON. Below is a snippet o ...