Create a Sql Azure Database with serverless tier using SDK - azure-sql-database

Currently, I create databases and attach them to an SQL elastic pool:
database = await sqlServer.Databases.Define(mainDb.DbName).WithExistingElasticPool(pool.Name).CreateAsync();
Instead, I want to create databases with tier "General Purpose: Serverless, Gen5, 1 vCore", but I couldn't find any method that offers that possibility.
This feature is still in preview, I can't find anything on the forums on this. How can I achieve this?

As an addendum to #Jim Xu accepted answer, the API has changed.
var database = sqlserver.Databases.Define("test").WithEdition("GeneralPurpose").WithServiceObjective("GP_S_Gen5_1").Create();
The WithEdition is now a DatabaseEdition edition type, and WithServiceObjective is now a ServiceObjectiveName. Both of these are muddled string enums with lists of version types. They do both also accept a .Parse() method. So the line should now be:
var database = sqlserver.Databases.Define("test")
.WithEdition(**Database.Edition.Parse("GeneralPurpose")**)
.WithServiceObjective(**ServiceObjectiveName.Parse("GP_S_Gen5_1")**)
.Create();

According to my test, we can use the following c# code to create "General Purpose: Serverless, Gen5, 1 vCore" database
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(client,key,tenant,AzureEnvironment.AzureGlobalCloud);
var azure = Azure.Configure().Authenticate(credentials).WithSubscription(SubscriptionId);
var sqlserver=azure.SqlServers.GetById("/subscriptions/<your subscrption id>/resourceGroups/<your resource group name>/providers/Microsoft.Sql/servers/<your server name>");
var database = sqlserver.Databases.Define("test").WithEdition("GeneralPurpose").WithServiceObjective("GP_S_Gen5_1").Create();
Console.WriteLine(database.ServiceLevelObjective);
Console.WriteLine(database.Edition);
Console.WriteLine(database.Name);
Console.ReadLine();

Please reference this tutorial: Create a new elastic database pool with C#.
It provides the code example about Create a new database in a pool:
Create a DataBaseCreateorUpdateProperties instance, and set the properties of the new database. Then call the CreateOrUpdate method with the resource group, server name, and new database name.
// Create a database: configure create or update parameters and properties explicitly
DatabaseCreateOrUpdateParameters newPooledDatabaseParameters = new DatabaseCreateOrUpdateParameters()
{
Location = currentServer.Location,
Properties = new DatabaseCreateOrUpdateProperties()
{
Edition = "Standard",
RequestedServiceObjectiveName = "ElasticPool",
ElasticPoolName = "ElasticPool1",
MaxSizeBytes = 268435456000, // 250 GB,
Collation = "SQL_Latin1_General_CP1_CI_AS"
}
};
var poolDbResponse = sqlClient.Databases.CreateOrUpdate("resourcegroup-name", "server-name", "Database2", newPooledDatabaseParameters);
Please try to replace "standard" with the price tier "General Purpose: Serverless, Gen5, 1 vCore".
Hope this helps.

Related

PowerBI API Clone Report and Dataset changing the datasource

I am developing an application in .NET6 using the PoweBI Client for managing workspaces, reports, datasets, etc.
The idea is that the application will be able to create client workspaces and will inherit reports and datasets from a main workspace. In the main workspace there will be reports published from PowerBI Desktop and therefore the respective dataset will be also there.
At the moment of the clone datasource database, user and password should be changed accordantly to match the workspace customer context. Using the following code I can list the reports on the main workspace (workspace_from_id) and I can create them on customer workspace (workspace_towa_id)
var reports_from = pbiClient.Reports.GetReports(workspace_from_id);
foreach (Report report_from in reports_from.Value)
{
Guid report_from_id = report_from.Id;
CloneReportRequest cloneReportRequest = new();
cloneReportRequest.TargetWorkspaceId = workspace_towa_id;
cloneReportRequest.TargetModelId = dataset_towa.Id;
cloneReportRequest.Name = report_from.Name;
Report report_towa = pbiClient.Reports.CloneReport(workspace_from_id, report_from_id, cloneReportRequest);
}
The problem of the above code is that the dataset is not cloned and the source dataset is used as shared dataset for both workspaces. I tried already to copy the dataset details and create a new one with different database using the following code:
CreateDatasetRequest createDatasetRequest = new();
createDatasetRequest.Name = dataset_from.Name;
createDatasetRequest.Datasources = new List<Datasource>();
createDatasetRequest.Tables = new List<Table>();
Datasources datasources_from = pbiClient.Datasets.GetDatasources(workspace_from_id, dataset_from_id);
foreach (Datasource datasource_from in datasources_from.Value)
{
//FOREACH DATASOURCE IN DATASET
Datasource datasource_towa = new ();
datasource_towa.Name = datasource_from.Name;
datasource_towa.DatasourceType = datasource_from.DatasourceType;
//CHANGE DATASOURCE CONNECTION DETAILS
DatasourceConnectionDetails datasourceConnectiondetails = datasource_from.ConnectionDetails;
datasourceConnectiondetails.Database = $"{Variables.reporting_db}_{group_towa.Name.ToLower()}";
datasource_towa.ConnectionDetails = datasourceConnectiondetails;
datasource_towa.ConnectionString = datasource_from.ConnectionString;
datasource_towa.GatewayId = datasource_from.GatewayId;
//ADD DATASOURCE INTO DATASET
createDatasetRequest.Datasources.Add(datasource_towa);
}
Tables tables_from = pbiClient.Datasets.GetTables(workspace_from_id, dataset_from_id); //WORKS FOR PUSH DATASET
foreach (Table table_from in tables_from.Value)
{
//FOREACH TABLE IN DATASET
Table table_towa = new ();
table_towa.Name = table_from.Name;
table_towa.Source = table_from.Source;
table_towa.Columns = table_from.Columns;
table_towa.Rows = table_from.Rows;
table_towa.Description = table_from.Description;
//ADD TABLE INTO DATASET
createDatasetRequest.Tables.Add(table_from);
}
The problem with the above code is that the pbiClient.Datasets.GetTables function is not working for normal datasets but is used only for push datasets. Finally without beeing able to get the Tables the following code is failing:
var dataset_towa = pbiClient.Datasets.PostDataset(workspace_towa_id, createDatasetRequest);
Finally discovered that also the pbiClient.Datasets.PostDataset method is used to post push dataset as described here: https://learn.microsoft.com/en-us/rest/api/power-bi/push-datasets/datasets-post-dataset
=======UPDATE 13/01/2023=======
Tried already a few other ways to clone the report and dataset like to create a datasource but for that we need a data gateway. In that case when the reports are already into a cloud like Azure for PostgreSQL we do need a gateway. On the other side I tried to create a Virtual Gateway in order to create datasource into this Gateway, but =Virtual Gateway is not supported by PowerBI Api and is only supported in premium capacities.
So seems that I cannot clone report together with a dataset and change the datasource.
Any ideas?
After a lot of hours researching I managed to download report from main workspace and upload them into customer workpaces by changing the datasource details.
Steps to perform:
Export report with PowerBI API /Export as stream into memory
Import report with PowerBI API /Imports as stream from memory (needs special treat to be sure that you read the whole stream from the HTTP Content / using SDK is not working)
Update report ConnectionDetails with PowerBI Client SDK /pbiClient.Datasets.UpdateDatasourcesInGroup (needs special treat to change only the server and database attribute without putting new instance of object)
Update datasource of the dataset with PowerBI Client SDK /pbiClient.Gateways.UpdateDatasource (needs special treat to give credentials as JSON)

How to show a table from a SQL Server database by using SqlKata?

I am trying to show a table from a database in my SQL Server 2017 by using SqlKata.
I have browsed for some researches. Based from one of the articles, I need to write this command var books = db.Query("Books").Get();
My question here is: Where do we put the command in a C# .NETCoreApp 1.1 target framework file? And how to run to display out the result?
If you have a cast class use
var books = db.Query("Books").Get<YouClass>();
But you dont have cast class -> use
var books = db.Query("Books").Get<dynamic>();
If you want logging execute query, write code startup.cs
var db = new QueryFactory(connection, new SqlServerCompiler());
// Log the compiled query to the console
db.Logger = compiled => {
Console.WriteLine(compiled.ToString()); //NLog - GrayLog - API - DB - TextFile - more..
};
etc. https://sqlkata.com/docs/execution/logging

Upload and Download error synchronizing Sql Server and Sql Azure - Sync Framework

I'm trying to synchronize an Sql Server database with SQL Azure Database (please be patient 'cause I don't fully understand Sync Framework). These are the requirements:
First: synchronize 1 table from Sql Azure to Sql Server
Second: synchronize 13 other tables (including the table I mentioned in the first step) from Sql Server to Azure.
I've created a console application, and this is the code:
1.I create one scope with the 13 tables:
DbSyncScopeDescription myScope = new DbSyncScopeDescription("alltablesyncgroup");
DbSyncTableDescription table = qlSyncDescriptionBuilder.GetDescriptionForTable("tablename", sqlServerConn);
myScope.Tables.Add(table); //repeated 13 times.
2.I Provision both data bases:
SqlSyncScopeProvisioning sqlAzureProv = new SqlSyncScopeProvisioning(sqlAzureConn,myScope);
if (!sqlAzureProv.ScopeExists("alltablesyncgroup"))
{
sqlAzureProv.Apply();
}
SqlSyncScopeProvisioning sqlServerProv = new SqlSyncScopeProvisioning(sqlServerConn, myScope);
if (!sqlServerProv.ScopeExists("alltablesyncgroup"))
{
sqlServerProv.Apply();
}
3.I create the SyncOrchestrator with the SyncDirectionOrder.Download to sync the firts table:
SqlConnection sqlServerConn = new SqlConnection(sqllocalConnectionString);
SqlConnection sqlAzureConn = new SqlConnection(sqlazureConnectionString);
SyncOrchestrator orch = new SyncOrchestrator
{
RemoteProvider = new SqlSyncProvider(scopeName, sqlAzureConn),
LocalProvider = new SqlSyncProvider(scopeName, sqlServerConn),
Direction = SyncDirectionOrder.Download
};
orch.Synchronize();
4.Later, I use the same function only changing the direction SyncDirectionOrder.Upload to sync the 13 remaining tables
SqlConnection sqlServerConn = new SqlConnection(sqllocalConnectionString);
SqlConnection sqlAzureConn = new SqlConnection(sqlazureConnectionString);
SyncOrchestrator orch = new SyncOrchestrator
{
RemoteProvider = new SqlSyncProvider(scopeName, sqlAzureConn),
LocalProvider = new SqlSyncProvider(scopeName, sqlServerConn),
Direction = SyncDirectionOrder.Upload
};
orch.Synchronize();
Now, here is the thing, obviously I'm doing it wrong 'cause when I download, the syncStats shows that a lot of change have been applied BUT I can't see it reflected on any data base and when I try to execute the Upload sync it seems to be going into a loop 'cause the Upload process doesn't stop.
Thanks!!!
first, you mentioned you only want to sync one table from Azure to your SQL Server but you're provisioning 13 tables in the scope. if you want one table, just provision a scope with one table. (e.g. one scope for the download with table, one scope for the upload with the rest of the tables)
to find out why rows are not synching, you can subscribe to the ApplyChangeFailed event for both sides, and check if there are conflicts or errors being encountered.
or you can enable Sync Framework tracing in verbose mode so you can see what's happening underneath.

Script table as CREATE TO by using vb.net

In SQL server I can create a table which is duplicate of another table with all constraints set in it. I can use script table as CREATE TO in SQL server management studio to do this. Then I can run the script in another database so that same table is recreated but without data. I want to do same by using vb.net code. Important point is that all the constraints and table properties are set properly.
You can use the SMO (SQL Server Management Objects) assembly to script out tables to a string inside your application. I'm using C# here, but the same can be done easily in VB.NET, too.
// Define your database and table you want to script out
string dbName = "YourDatabase";
string tableName = "YourTable";
// set up the SMO server objects - I'm using "integrated security" here for simplicity
Server srv = new Server();
srv.ConnectionContext.LoginSecure = true;
srv.ConnectionContext.ServerInstance = "YourSQLServerInstance";
// get the database in question
Database db = new Database();
db = srv.Databases[dbName];
StringBuilder sb = new StringBuilder();
// define the scripting options - what options to include or not
ScriptingOptions options = new ScriptingOptions();
options.ClusteredIndexes = true;
options.Default = true;
options.DriAll = true;
options.Indexes = true;
options.IncludeHeaders = true;
// script out the table's creation
Table tbl = db.Tables[tableName];
StringCollection coll = tbl.Script(options);
foreach (string str in coll)
{
sb.Append(str);
sb.Append(Environment.NewLine);
}
// you can get the string that makes up the CREATE script here
// do with this CREATE script whatever you like!
string createScript = sb.ToString();
You need to reference several SMO assemblies.
Read more about SMO and how to use it here:
Getting Started with SQL Server Management Objects (SMO)
Generate Scripts for database objects with SMO for SQL Server

Failure to create a SQL Azure login with SMO

The following piece of code works with regular SQL and SMO. I'm trying to get it to work with SQL Azure. According to this MSDN article, a limited subset of functionality that I need (database and login creation) should be supported. All the business checking whether an object exists will also fail: server.Logins[loginName] != null or server.Databases.Contains(dbName). I can create a database if I dont check whether it exists or not, but i cant create a login. Anyone else ran into the same problem?
string connectionString =
"Server=tcp:XXXXXX.database.windows.net;Database=MyDatabase;User ID=XXXXXXX;Password=XXXXXX;Trusted_Connection=False;Encrypt=True;TrustServerCertificate=true;"
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
ServerConnection serverConnection = new ServerConnection(connection);
Server server = new Server(serverConnection);
Login login = new Login(server, "NewLogin");
login.LoginType = LoginType.SqlLogin;
login.Create("NewStrongPwd123***");
}
Create failed for Login 'NewLogin'.
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.CreateImpl()
at Microsoft.SqlServer.Management.Smo.Login.Create(SecureString password)
at Microsoft.SqlServer.Management.Smo.Login.Create(String password)
Proposed answers to this question were identified on the MSDN Forum including a working approach. Please take a look at: http://social.msdn.microsoft.com/Forums/en-US/ssdsgetstarted/thread/26e42082-e649-4cde-916d-c1da2275e377