{"id":15291246,"url":"https://github.com/azure/azure-kusto-go","last_synced_at":"2025-05-15T04:07:32.795Z","repository":{"id":37407153,"uuid":"203177617","full_name":"Azure/azure-kusto-go","owner":"Azure","description":"Azure Data Explorer (Kusto) SDK for Go","archived":false,"fork":false,"pushed_at":"2025-04-28T05:17:32.000Z","size":3866,"stargazers_count":59,"open_issues_count":3,"forks_count":44,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-05-10T00:11:58.073Z","etag":null,"topics":["azure","azure-data-explorer","golang","kusto"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Azure.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-19T13:23:59.000Z","updated_at":"2025-04-28T05:08:08.000Z","dependencies_parsed_at":"2023-09-27T12:42:32.701Z","dependency_job_id":"c3e3e3e7-46d3-40dd-bcb8-161801beae92","html_url":"https://github.com/Azure/azure-kusto-go","commit_stats":{"total_commits":273,"total_committers":25,"mean_commits":10.92,"dds":"0.41025641025641024","last_synced_commit":"5a0ce3110ce559fa438a48ec48c3ec0c4daffce1"},"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azure%2Fazure-kusto-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azure%2Fazure-kusto-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azure%2Fazure-kusto-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azure%2Fazure-kusto-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Azure","download_url":"https://codeload.github.com/Azure/azure-kusto-go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254270646,"owners_count":22042859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","azure-data-explorer","golang","kusto"],"created_at":"2024-09-30T16:11:38.130Z","updated_at":"2025-05-15T04:07:27.773Z","avatar_url":"https://github.com/Azure.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Microsoft Azure Data Explorer (Kusto) [![GoDoc](https://godoc.org/github.com/Azure/azure-kusto-go?status.svg)](https://pkg.go.dev/github.com/Azure/azure-kusto-go/azkustodata) [![GoDoc](https://godoc.org/github.com/Azure/azure-kusto-go?status.svg)](https://pkg.go.dev/github.com/Azure/azure-kusto-go/azkustoingest)\r\n\r\n- [About Azure Data Explorer](https://azure.microsoft.com/en-us/services/data-explorer/)\r\n- [Data Client documentation](https://godoc.org/github.com/Azure/azure-kusto-go/azkustodata)\r\n- [Ingest Client documentation](https://godoc.org/github.com/Azure/azure-kusto-go/azkustoingest)\r\n\r\n# Version 1.0.0-preview Released (BREAKING CHANGES)\r\nVersion 1.0.0-preview introduced a significant change to the package structure, aligning Azure-Kusto-Go with all other Kusto SDKs structure.\r\nThe original package, `github.com/Azure/azure-kusto-go` is no longer published.\r\nInstead, there are two new packages:\r\n- `github.com/Azure/azure-kusto-go/azkustodata` - for query and management commands.\r\n- `github.com/Azure/azure-kusto-go/azkustoingest` - for interacting with the ingesting data.\r\n\r\nFor more information, see the [migration guide](MIGRATION.md) and [changelog](CHANGELOG.md)\r\n\r\n\r\n## Intro\r\nThis is a data plane SDK (it is for interacting with Azure Data Explorer (Kusto) service). For the control plane (resource administration), go [here](https://github.com/Azure/azure-sdk-for-go/tree/master/services/kusto/mgmt).\r\n\r\nUse `github.com/Azure/azure-kusto-go/azkustodata` in your application to:\r\n\r\n- Query Kusto/Azure Data Explorer clusters for rows, optionally into structs.\r\n\r\nUse `github.com/Azure/azure-kusto-go/azkustoingest` in your application to:\r\n- Import data into Kusto from local file, Azure Blob Storage file, Stream, or an `io.Reader`.\r\n\r\n\r\nKey links:\r\n- [Source code](https://github.com/Azure/azure-kusto-go)\r\n- [API Reference Documentation](https://pkg.go.dev/github.com/Azure/azure-kusto-go)\r\n- [Product documentation](https://azure.microsoft.com/en-us/services/data-explorer/)\r\n- [Samples](https://pkg.go.dev/github.com/Azure/azure-kusto-go#readme-examples)\r\n\r\n## Key concepts\r\n\r\nAzure Data Explorer is a fully managed, high-performance, big data analytics platform that makes it easy to analyze high volumes of data in near real time. The Azure Data Explorer toolbox gives you an end-to-end solution for data ingestion, query, visualization, and management.\r\n\r\nAn Azure Data Explorer (Kusto) [**cluster**](https://docs.microsoft.com/azure/event-hubs/event-hubs-features#namespace) can have multiple databases. Each database, in turn, contains [**tables**](https://docs.microsoft.com/azure/event-hubs/event-hubs-features#partitions) which store data.\r\n\r\nQuery Azure Data Explorer with the [Kusto Query Language (KQL)](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/), an open-source language initially invented by the team. The language is simple to understand and learn, and highly productive. You can use simple operators and advanced analytics.\r\n\r\nFor more information about Azure Data Explorer (Kusto), its features, and relevant terminology can be found here: [link](https://learn.microsoft.com/en-us/azure/data-explorer/data-explorer-overview)\r\n\r\n\r\n## Getting started\r\n\r\n### Install the package\r\n\r\nInstall the Kusto/Azure Data Explorer client module for Go with `go get`:\r\n\r\n```bash\r\ngo get github.com/Azure/azure-kusto-go\r\n```\r\n\r\n### Prerequisites\r\n\r\n- Go, version 1.22 or higher\r\n- An [Azure subscription](https://azure.microsoft.com/free/)\r\n- An [Azure Data Explorer Cluster](https://learn.microsoft.com/en-us/azure/data-explorer/).\r\n- An Azure Data Explorer Database. You can create a Database in your Azure Data Explorer Cluster using the [Azure Portal](https://learn.microsoft.com/en-us/azure/data-explorer/create-cluster-database-portal).\r\n\r\n## Examples\r\n\r\nExamples for various scenarios can be found on [pkg.go.dev](https://pkg.go.dev/github.com/Azure/azure-kusto-go#readme-examples) or in the example*_test.go files in our GitHub repo for [azure-kusto-go](https://github.com/Azure/azure-kusto-go/tree/master/kusto).\r\n\r\n### Create the connection string\r\n\r\nAzure Data Explorer (Kusto) connection strings are created using a connection string builder for an existing Azure Data Explorer (Kusto) cluster endpoint of the form `https://\u003ccluster name\u003e.\u003clocation\u003e.kusto.windows.net`.\r\n\r\n```go\r\nkustoConnectionStringBuilder := azkustodata.NewConnectionStringBuilder(endpoint)\r\n```\r\n\r\n### Create and authenticate the client\r\n\r\nAzure Data Explorer (Kusto) clients are created from a connection string and authenticated using a credential from the [Azure Identity package][azure_identity_pkg], like [DefaultAzureCredential][default_azure_credential].\r\nYou can also authenticate a client using a system- or user-assigned managed identity with Azure Active Directory (AAD) credentials.\r\n\r\n#### Using the `DefaultAzureCredential`\r\n\r\n```go\r\n// kusto package is: github.com/Azure/azure-kusto-go/azkustodata\r\n\r\n// Initialize a new kusto client using the default Azure credential\r\nkustoConnectionString := kustoConnectionStringBuilder.WithDefaultAzureCredential()\r\nclient, err = azkustodata.New(kustoConnectionString)\r\nif err != nil {\r\n\tpanic(\"add error handling\")\r\n}\r\n// Be sure to close the client when you're done. (Error handling omitted for brevity.)\r\ndefer client.Close()\r\n```\r\n\r\n#### Using the `az cli`\r\n\r\n```go\r\nkustoConnectionString := kustoConnectionStringBuilder.WithAzCli()\r\nclient, err = azkustodata.New(kustoConnectionString)\r\n```\r\n\r\n#### Using a system-assigned managed identity\r\n\r\n```go\r\nkustoConnectionString := kustoConnectionStringBuilder.WithSystemManagedIdentity()\r\nclient, err = azkustodata.New(kustoConnectionString)\r\n```\r\n\r\n#### Using a user-assigned managed identity\r\n\r\n```go\r\nkustoConnectionString := kustoConnectionStringBuilder.WithUserAssignedIdentityClientId(clientID)\r\nclient, err = azkustodata.New(kustoConnectionString)\r\n```\r\n\r\n#### Using a k8s workload identity\r\n\r\n```go\r\nkustoConnectionString := kustoConnectionStringBuilder.WithKubernetesWorkloadIdentity(appId, tokenFilePath, authorityID)\r\nclient, err = kusto.New(kustoConnectionString)\r\n```\r\n\r\n#### Using a bearer token\r\n\r\n```go\r\nkustoConnectionString := kustoConnectionStringBuilder.WithApplicationToken(appId, token)\r\nclient, err = azkustodata.New(kustoConnectionString)\r\n```\r\n\r\n#### Using an app id and secret\r\n\r\n```go\r\nkustoConnectionString := kustoConnectionStringBuilder.WithAadAppKey(clientID, clientSecret, tenantID)\r\nclient, err = azkustodata.New(kustoConnectionString)\r\n```\r\n\r\n#### Using an application certificate\r\n\r\n```go\r\nkustoConnectionString := kustoConnectionStringBuilder.WithAppCertificate(appId, certificate, thumbprint, sendCertChain, authorityID)\r\nclient, err = azkustodata.New(kustoConnectionString)\r\n```\r\n\r\n### Querying\r\n\r\n#### Simple queries\r\n\r\n* Work for all types of requests, including queries and management commands.\r\n* Limited to queries that can be built using a string literal known at compile time.\r\n\r\nThe simplest queries can be built using `kql.New`:\r\n\r\n```go\r\nquery := kql.New(\"systemNodes | project CollectionTime, NodeId\")\r\n```\r\n\r\nQueries can only be built using a string literals known at compile time, and special methods for specific parts of the query.  \r\nThe reason for this is to discourage the use of string concatenation to build queries, which can lead to security vulnerabilities.\r\n\r\n#### Queries with parameters\r\n\r\n* Can re-use the same query with different parameters.\r\n* Only work for queries, management commands are not supported.\r\n\r\nIt is recommended to use parameters for queries that contain user input.  \r\nManagement commands can not use parameters, and therefore should be built using the builder (see next section).\r\n\r\nParameters can be implicitly referenced in a query:\r\n\r\n```go\r\nquery := kql.New(\"systemNodes | project CollectionTime, NodeId | where CollectionTime \u003e startTime and NodeId == nodeIdValue\")\r\n```\r\n\r\nHere, `startTime` and `nodeIdValue` are parameters that can be passed to the query.\r\n\r\nTo Pass the parameters values to the query, create `kql.Parameters`:\r\n\r\n```\r\nparams :=  kql.NewParameters().AddDateTime(\"startTime\", dt).AddInt(\"nodeIdValue\", 1)\r\n```\r\n\r\nAnd then pass it to the `Query` method, as an option:\r\n```go\r\nresults, err := client.Query(ctx, database, query, QueryParameters(params))\r\nif err != nil {\r\n    panic(\"add error handling\")\r\n}\r\n\r\n// You can see the generated parameters using the ToDeclarationString() method:\r\nfmt.Println(params.ToDeclarationString()) // declare query_parameters(startTime:datetime, nodeIdValue:int);\r\n\r\n// You can then use the same query with different parameters:\r\nparams2 :=  kql.NewParameters().AddDateTime(\"startTime\", dt).AddInt(\"nodeIdValue\", 2)\r\ndataset, err = client.Query(ctx, database, query, QueryParameters(params2))\r\n```\r\n\r\n#### Queries with inline parameters\r\n* Works for queries and management commands.\r\n* More involved building of queries, but allows for more flexibility.\r\n\r\nQueries with runtime data can be built using `kql.New`.\r\nThe builder will only accept the correct types for each part of the query, and will escape any special characters in the data.\r\n\r\nFor example, here is a query that dynamically accepts values for the table name, and the comparison parameters for the columns:\r\n\r\n```go\r\ndt, _ := time.Parse(time.RFC3339Nano, \"2020-03-04T14:05:01.3109965Z\")\r\ntableName := \"system nodes\"\r\nvalue := 1\r\n\r\nquery := kql.New(\"\")\r\n            .AddTable(tableName)\r\n            .AddLiteral(\" | where CollectionTime == \").AddDateTime(dt)\r\n            .AddLiteral(\" and \")\r\n            .AddLiteral(\"NodeId == \").AddInt(value)\r\n\r\n// To view the query string, use the String() method:\r\nfmt.Println(query.String())\r\n// Output: ['system nodes'] | where CollectionTime == datetime(2020-03-04T14:05:01.3109965Z) and NodeId == int(1)\r\n```\r\n\r\nBuilding queries like this is useful for queries that are built from user input, or for queries that are built from a template, and are valid for management commands too.\r\n\r\n\r\n\r\n#### Query For Rows\r\n\r\nThe kusto `table` package queries data into a ***table.Row** which can be printed or have the column data extracted.\r\n\r\n```go\r\n// Query our database table \"systemNodes\" for the CollectionTimes and the NodeIds.\r\ndataset, err := client.IterativeQuery(ctx, \"database\", query)\r\nif err != nil {\r\n\tpanic(\"add error handling\")\r\n}\r\n// Don't forget to close the dataset when you're done. \r\ndefer dataset.Close()\r\n\r\nprimaryResult := \u003c-dataset.Tables() // The first table in the dataset will be the primary results.\r\n\r\n// Make sure to check for errors.\r\nif primaryResult.Err() != nil {\r\n    panic(\"add error handling\")\r\n}\r\n\r\nfor rowResult := range primaryResult.Table().Rows() {\r\n\tif rowResult.Err() != nil {\r\n        panic(\"add error handling\")\r\n\t}\r\n\trow := rowResult.Row()\r\n\t\r\n    fmt.Println(row) // As a convenience, printing a *table.Row will output csv\r\n\t// or Access the columns directly\r\n    fmt.Println(row.IntByName(\"EventId\"))\r\n    fmt.Println(row.StringByIndex(1))\r\n}\r\n\r\n// Alternatively, use the `Query` method to get all of the data at once.\r\ndataset, err := client.Query(ctx, \"database\", query)\r\nif err != nil {\r\n    panic(\"add error handling\")\r\n}\r\n\r\nfor _, row := range dataset.Tables()[0].Rows() {\r\n    fmt.Println(row) // As a convenience, printing a *table.Row will output csv\r\n    // or Access the columns directly\r\n    fmt.Println(row.IntByName(\"EventId\"))\r\n    fmt.Println(row.StringByIndex(1))\r\n}\r\n\r\n```\r\n\r\n#### Query Into Structs\r\n\r\nUsers will often want to turn the returned data into Go structs that are easier to work with.  The ***table.Row** object\r\nthat is returned supports this via the `.ToStruct()` method.\r\n\r\n```go\r\n// NodeRec represents our Kusto data that will be returned.\r\ntype NodeRec struct {\r\n\t// ID is the table's NodeId. We use the field tag here to instruct our client to convert NodeId to ID.\r\n\tID int64 `kusto:\"NodeId\"`\r\n\t// CollectionTime is Go representation of the Kusto datetime type.\r\n\tCollectionTime time.Time\r\n}\r\n\r\ndataset, err := client.IterativeQuery(ctx, \"database\", query)\r\nif err != nil {\r\npanic(\"add error handling\")\r\n}\r\n// Don't forget to close the dataset when you're done. \r\ndefer dataset.Close()\r\n\r\nprimaryResult := \u003c-dataset.Tables() // The first table in the dataset will be the primary results.\r\n\r\n// Make sure to check for errors.\r\nif primaryResult.Err() != nil {\r\npanic(\"add error handling\")\r\n}\r\n\r\nfor result := range query.ToStructsIterative[NodeRec](primaryResult.Table()) {\r\n    if result.Err() != nil {\r\n        panic(\"add error handling\")\r\n    }\r\n    node := result.Struct()\r\n    fmt.Println(node.ID)\r\n}\t\r\n\r\n// Or use the `Query` method to get all of the data at once.\r\ndataset, err := client.Query(ctx, \"database\", query)\r\nif err != nil {\r\n    panic(\"add error handling\")\r\n}\r\n\r\n// You can use the `ToStructs` method directly on the dataset, or on a specific table.\r\nstructs, err := query.ToStructs[NodeRec](dataset)\r\nif err != nil {\r\n    panic(\"add error handling\")\r\n}\r\n\r\nfor _, node := range structs {\r\n    fmt.Println(node.ID)\r\n}\r\n\r\n```\r\n\r\n### Ingestion\r\n\r\nThe `azkustoingest` package provides access to Kusto's ingestion service for importing data into Kusto. This requires\r\nsome prerequisite knowledge of acceptable data formats, mapping references, etc.\r\n\r\nThat documentation can be found [here](https://docs.microsoft.com/en-us/azure/kusto/management/data-ingestion/)\r\n\r\nIf ingesting data from memory, it is suggested that you stream the data in via `FromReader()` passing in the reader\r\nfrom an `io.Pipe()`. The data will not begin ingestion until the writer closes.\r\n\r\n\r\n#### Creating a queued ingestion client\r\nThere are a few types of ingestion clients:\r\n* Queued Ingest - `azkustoingest.New()` - the default client, uses queues and batching to ingest data. Most reliable.\r\n* Streaming Ingest - `azkustoingest.NewStreaming()` - Directly streams data into the engine. Fast, but is limited with size and can fail.\r\n* Managed Streaming Ingest - `azkustoingest.NewManaged()` - Combines a streaming ingest client with a queued ingest client to provide a reliable ingestion method that is fast and can ingest large amounts of data.\r\n  Managed Streaming will try to stream the data, and if it fails multiple times, it will fall back to a queued ingestion.\r\n\r\nTo create an ingestion client, pass a Connection String, and additional options. \r\n```go\r\n// queued client\r\nkustoConnectionString := azkustodata.NewConnectionStringBuilder(\"\u003ccluster\u003e\").WithDefaultAzureCredential()\r\n\r\n// Queued ingestion client\r\nin, err := azkustoingest.New(kustoConnectionString)\r\nif err != nil {\r\n\tpanic(\"add error handling\")\r\n}\r\n\r\n// Streaming ingestion client with default database and table\r\nin, err := azkustoingest.NewStreaming(kustoConnectionString, azkustoingest.WithDefaultDatabase(\"database\"), azkustoingest.WithDefaultTable(\"table\"))\r\n\r\n// Managed streaming ingest client\r\nin, err := azkustoingest.NewManaged(kustoConnectionString, azkustoingest.WithDefaultDatabase(\"database\"), azkustoingest.WithDefaultTable(\"table\"))\r\n\r\n// Be sure to close the ingestor when you're done. (Error handling omitted for brevity.)\r\ndefer in.Close()\r\n```\r\n\r\nQueued ingestion client requires the url of the ingestion endpoint, usually starting with `ingest-`, and for streaming ingestion it's the opposite. \r\n\r\nThe SDK will infer this endpoint from the given url. In case this is not wanted, you can use an option to disable it:\r\n\r\n```go\r\nin, err := azkustoingest.New(kustoConnectionString, azkustoingest.WithoutEndpointCorrection())\r\n// Similarly, you can use azkustoingest.WithCustomIngestConnectionString() to provide a different query and ingest endpoint to a managed streaming ingest client.\r\nin, err := azkustoingest.NewManaged(kustoConnectionString, azkustoingest.WithCustomIngestConnectionString(azkustodata.NewConnectionStringBuilder(\"https://ingest-\u003ccluster\u003e\").WithDefaultAzureCredential()))\r\n```\r\n\r\n#### Ingestion From a File\r\n\r\nIngesting a local file requires simply passing the path to the file to be ingested:\r\n\r\n```go\r\nif _, err := in.FromFile(ctx, \"/path/to/a/local/file\"); err != nil {\r\n\tpanic(\"add error handling\")\r\n}\r\n```\r\n\r\n`FromFile()` will accept Unix path names on Unix platforms and Windows path names on Windows platforms.\r\nThe file will not be deleted after upload (there is an option that will allow that though).\r\n\r\n#### Ingestion From a Blob Storage File\r\n\r\nThis package will also accept ingestion from an Azure Blob Storage file:\r\n\r\n```go\r\nif _, err := in.FromFile(ctx, \"https://myaccount.blob.core.windows.net/$root/myblob\"); err != nil {\r\n\tpanic(\"add error handling\")\r\n}\r\n```\r\n\r\nThis will ingest a file from Azure Blob Storage. We only support `https://` paths and your domain name may differ than what is here.\r\n\r\n#### Ingestion from an io.Reader\r\n\r\nSometimes you want to ingest a stream of data that you have in memory without writing to disk.  You can do this simply by chunking the\r\ndata via an `io.Reader`.\r\n\r\n```go\r\nr, w := io.Pipe()\r\n\r\nenc := json.NewEncoder(w)\r\ngo func() {\r\n\tdefer w.Close()\r\n\tfor _, data := range dataSet {\r\n\t\tif err := enc.Encode(data); err != nil {\r\n\t\t\tpanic(\"add error handling\")\r\n\t\t}\r\n\t}\r\n}()\r\n\r\nif _, err := in.FromReader(ctx, r); err != nil {\r\n\tpanic(\"add error handling\")\r\n}\r\n```\r\n\r\nIt is important to remember that `FromReader()` will terminate when it receives an `io.EOF` from the `io.Reader`.  Use `io.Readers` that won't\r\nreturn `io.EOF` until the `io.Writer` is closed (such as `io.Pipe`).\r\n\r\n## Best Practices\r\nSee the SDK [best practices guide](https://docs.microsoft.com/azure/data-explorer/kusto/api/netfx/kusto-ingest-best-practices), which though written for the .NET SDK, applies similarly here.\r\n\r\n## Contributing\r\n\r\nThis project welcomes contributions and suggestions.  Most contributions require you to agree to a\r\nContributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us\r\nthe rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.\r\n\r\nWhen you submit a pull request, a CLA bot will automatically determine whether you need to provide\r\na CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions\r\nprovided by the bot. You will only need to do this once across all repos using our CLA.\r\n\r\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).\r\nFor more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or\r\ncontact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\r\n\r\n## Looking for SDKs for other languages/platforms?\r\n\r\n- [Node](https://github.com/azure/azure-kusto-node)\r\n- [Java](https://github.com/azure/azure-kusto-java)\r\n- [.NET](https://docs.microsoft.com/en-us/azure/kusto/api/netfx/about-the-sdk)\r\n- [Python](https://github.com/Azure/azure-kusto-python)\r\n- [Azure CLI](https://learn.microsoft.com/en-us/azure/data-explorer/create-cluster-database-cli)\r\n- [PowerShell](https://learn.microsoft.com/en-us/azure/data-explorer/create-cluster-database-powershell)\r\n- [Azure Resource Manager template](https://learn.microsoft.com/en-us/azure/data-explorer/create-cluster-database-resource-manager)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazure%2Fazure-kusto-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazure%2Fazure-kusto-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazure%2Fazure-kusto-go/lists"}