I started to upgrade my .NET 5/6 applications to .NET 7, I also updated from EF6 to EF7, which seems to be more difficult than expected :-(
I managed to find out that there were breaking changes in the new SqlClient (5.0.1) library, which now forces you to turn off encryption or trust the server certificate:
Encrypt = false; or TrustServerCertificate = yes
After I have set these properties in the connection string, I was again able to connect to my database.
BUT, I am using a code first approach, this means my app is creating / migrating the database if it does not exist or needs migration.
I am now running into the issue that my app is not able to create an empty database anymore. I am still getting an exception
Microsoft.Data.SqlClient.SqlException
Cannot open database "XXX" requested by the login. The login failed.
Login failed for user 'YYY\ZZZ'.
This only happens when I am trying to create a new database.
If I create an empty database (no scheme) manually on my SQL Server Express, all works fine, the scheme gets created and migrations applied. The issue is only the initial creation of the database itself.
Application and SQL Server Express are running on the same machine, SQL Server runs in mixed authentication mode. "Trusted Connection" is enabled in my connection string which looks like this:
Server =.\\SQLExpress; Database = TEST_DB; Trusted_Connection = Yes; Connection Timeout = 5; Encrypt = false;
Before I updated to .NET 7 everything worked fine with the exact same connection string.
Any ideas?
I have a PostgreSQL database deployed in Google Cloud that I am trying to connect to from a Cloud Run instance. I have tried the following two packages, both of them eventually leading to the same exception:
https://pub.dev/packages/postgres
https://pub.dev/packages/database_adapter_postgre
The exception I am getting is:
SocketException: Failed host lookup: '/cloudsql/{INSTANCE_CONNECTION_NAME}' (OS Error: Name or service not known, errno = -2)
I get here both times when trying to establish the connection, so in the case of the first package:
connection = new PostgreSQLConnection(
'/cloudsql/{INSTANCE_CONNECTION_NAME}',
5432,
'postgres',
username: 'username',
password: 'password');
await connection.open(); // <-- exception thrown here
I have tried changing the host string to /cloudsql/INSTANCE_CONNECTION_NAME}/.s.PGSQL.5432, but that did not work. My first thought were permissions, the service account the Cloud Run instance is using (xxx-compute#developer.gserviceaccount.com) has the Cloud SQL Editor role (tried Client and Admin too).
Running the same database code locally from a dart console app, I can connect to my database via its public IP address as the host with both packages, so the database itself is up and running.
Can someone point me in the right direction with this exception/have an example code for any of the packages above to show how to connect it to a Cloud SQL instance from a Cloud Run?
Edit:
I tried setting up a proxy locally to test out if the connection is wrong like so:
.\cloud_sql_proxy.exe -instances={INSTANCE_CONNECTION_NAME}=tcp:5433 psql
Then changing the connection host value in the code to localhost, and the port to 5433.
To my surprise it works - so from locally I am seemingly able to connect to the DB using that connection string. It still doesn't work when I use it from a Cloud Run instance though. Any help is appreciated!
It seems dart doesn't support connection through unix socket, you need to configure a IP (public or private, as you need).
Alternatively you can use pg which support unix socket connection
Hope this helps.
Just for those who come across this question in the future:
as it stands right now, I had to resort to the suggestion posted by Daniele Ricci and use the public IP for the database. The one thing to point out here was that since Cloud Runs don't have a static IPv4 address to run from, the DB had to be set to allow connections from anywhere (had to add an authorized connection from 0.0.0.0/0), which is unsafe. Until the kind development team of dart figures out how to use UNIX sockets, this seems to be the only way of getting it to work.
Not having actually tested this myself, according to the source code of the postgres package, you have to specify that you want a Unix socket:
connection = PostgreSQLConnection(
...
isUnixSocket: true, // <-- here
);
The default is false.
The host you pass is must also be valid. The docs say:
[host] must be a hostname, e.g. "foobar.com" or IP address. Do not include scheme or port.
I was struggling with the same issue.
The solution is to create a connection as follows:
PostgreSQLConnection getProdConnection() {
final String connectionName = Platform.environment['CLOUD_SQL_CONNECTION_NAME']!;
final String databaseName = Platform.environment['DB_NAME']!;
final String user = Platform.environment['DB_USER']!;
final String password = Platform.environment['DB_PASS']!;
final String socketPath = '/cloudsql/$connectionName/.s.PGSQL.5432';
return PostgreSQLConnection(
socketPath,
5432,
databaseName,
username: user,
password: password,
isUnixSocket: true,
);
}
Then when you create a Cloud Run service, you need to define 'Enviroment variables' as follows.
You also need to select your sql instance in the 'connections' tab.
Then the last thing needed is to configure a Cloud Run service account.
Then the connection to instance should be successful and there should no longer be a need for a 0.0.0.0/0 connection.
However, if you try to run this connection locally on a Windows device during development the connection will not be allowed and you will be presented with this error message: 'Unix domain sockets are not available on this operating system.'
Therefore, I recommend that you open Google SQL networking to your public address and define a local environment using the 'Public IP address' of your SQL instance.
For more information on this topic, I can recommend these resources that have guided me to the right solution:
https://cloud.google.com/sql/docs/postgres/connect-instance-cloud-run#console_5
https://github.com/dart-lang/sdk/issues/47899
I've been trying to connect to my Cloud SQL instance using the pg module but haven't been successful so far.
I've looked around a lot online but couldn't understand much on the topic. I also would like to deploy my Express app on Cloud Run at some point and have it connect to my Cloud SQL instance but I don't know how to go about doing that.
Here's a list of things I don't understand and would like a brief explanation on:
What are Unix socket connections and why should I use them over normal connections?
What is a Cloud SQL Proxy? Do I need to use it? If so, why?
Would I need to do any extra work to connect to my Cloud SQL instance from Cloud Run?
Here are all the connection objects and connection strings I have tried with the pg.Client object:
First connection string: postgresql+psycopg2://postgres:password#/cloudsql/myapp:us-central1:mydb?host=/var/lib/postgresql
Second connection string: postgresql://postgres:password#hostip:5432/myapp:us-central1:mydb
Third connection string: postgresql://postgres:password#hostip:5432/sarcdb
Connection object: { host: "/cloudsql/myapp:us-central1:mydb", username: "postgres", password: "password", database: "mydb" }
All of these give me a Connection terminated unexpectedly error.
The Cloud Functions documentation for Node.js & Cloud SQL (scroll down to PostgreSQL) has applicable information on structuring the connection string and the additional configuration needed for credentials.
Once that's in place for your app, you'll need to add the Cloud SQL instance to your Cloud Run service before it will be able to use that connection string to reach the database.
Here's directly copying the code sample from the docs, with Cloud Run the max configuration of 1 might not keep pace with other concurrency settings.
const pg = require('pg');
/**
* TODO(developer): specify SQL connection details
*/
const connectionName =
process.env.INSTANCE_CONNECTION_NAME || '<YOUR INSTANCE CONNECTION NAME>';
const dbUser = process.env.SQL_USER || '<YOUR DB USER>';
const dbPassword = process.env.SQL_PASSWORD || '<YOUR DB PASSWORD>';
const dbName = process.env.SQL_NAME || '<YOUR DB NAME>';
const pgConfig = {
max: 1,
user: dbUser,
password: dbPassword,
database: dbName,
};
if (process.env.NODE_ENV === 'production') {
pgConfig.host = `/cloudsql/${connectionName}`;
}
// Connection pools reuse connections between invocations,
// and handle dropped or expired connections automatically.
let pgPool;
exports.postgresDemo = (req, res) => {
// Initialize the pool lazily, in case SQL access isn't needed for this
// GCF instance. Doing so minimizes the number of active SQL connections,
// which helps keep your GCF instances under SQL connection limits.
if (!pgPool) {
pgPool = new pg.Pool(pgConfig);
}
pgPool.query('SELECT NOW() as now', (err, results) => {
if (err) {
console.error(err);
res.status(500).send(err);
} else {
res.send(JSON.stringify(results));
}
});
// Close any SQL resources that were declared inside this function.
// Keep any declared in global scope (e.g. mysqlPool) for later reuse.
};
What are Unix socket connections and why should I use them over normal connections?
A Unix domain socket is a socket for interprocess communication. If you have the choice between communication between a TCP connection and a Unix domain socket, the Unix domain socket is likely faster.
What is a Cloud SQL Proxy? Do I need to use it? If so, why?
The Cloud SQL proxy allows you to authenticate a connection to connect to your database using IAM permissions of a service account.
Since Cloud SQL is a cloud database, it requires (by default) some form of authentication to help it remain secure. The proxy is a more secure method of connecting compared to a self-managed SSL Certificate or a whitelisted IP address.
Would I need to do any extra work to connect to my Cloud SQL instance from Cloud Run?
Cloud Run takes care of running the proxy for you, but you need to do the following:
Enable the Cloud SQL Admin API
Add the Cloud SQL instance to your Run deployment(follow these steps).
Ensure that the service account running your code has the Cloud SQL Client IAM permissions (this is done for the default service account by step 2)
Configure your application to connect with /cloudsql/INSTANCE_CONNECTION_NAME
I am trying to connect DB2 Server with ODBC, which is working fine if I specify Database in connection string.
driver = 'IBM DB2 ODBC DRIVER'
server = '10.30.30.114'
port = '50000'
protocol = 'TCPIP'
database = 'SAMPLE'
user = 'administrator'
pass = 'password'
DBI.connect("DBI:ODBC:Driver=#{driver};HostName=#{server};Port=#{port};Protocol=#{protocol};Database=#{database};Uid=#{user};Pwd=#{pass};")
The issue is I will not be knowing the database name in advance at the time of connecting to the server. I want the list of databases on the server and then tables in those databases, how should I approach?
You cannot "connect to a DB2 server" via ODBC; you can only connect to a database, for which you obviously need to specify the database name. You could use the DB2 C/C++ API calls db2DbDirOpenScan and db2DbDirGetNextEntry to list the database directory, but this code will need to be executed on the server itself, otherwise it will attempt to list the database catalog on the client machine.
IF you are connecting to DB2 for i server (formerly DB2 UDB on OS/400) --
Initially connect using hostname, allowing database to default. You can then get a list of databases in the DB2 for i SYSCATALOGS view. Your query might look like this:
SELECT catalog_name, -- database name
catalog_text -- DB description
FROM QSYS2.SYSCATALOGS
WHERE catalog_type='LOCAL' -- local to that host
AND catalog_status='AVAILABLE' -- REMOTE catalogs are 'UNKNOWN' status
You could then connect to that database if . Once connected to the appropriate database, you could query other DB2 for i catalog views such as SYSSCHEMAS and SYSTABLES. ODBC/JDBC Catalog views and ANS/ISO Catalog views would also be available.
Other API's are available outside of an ODBC connection via IBM i Access, if you prefer.
I use code-first in my project and deploy on host but I get error
CREATE DATABASE permission denied in database 'master'.
This is my connection string:
<add name="DefaultConnection"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-test-2012615153521;Integrated Security=False"
providerName="System.Data.SqlClient;User ID=test;Password=test"/>
I had the same problem. This what worked for me:
Go to SQL Server Management Studio and run it as Administrator.
Choose Security -> Then Logins
Choose the usernames or whatever users that will access your database under the Logins and Double Click it.
Give them a Server Roles that will give them credentials to create database. On my case, public was already checked so I checked dbcreator and sysadmin.
Run update-database again on Package Manager Console. Database should now successfully created.
Here is an image so that you can get the bigger picture, I blurred my credentials of course:
Be sure you have permission to create db.(as user2012810 mentioned.)
or
It seems that your code first use another (or default) connection string.
Have you set connection name on your context class?
public class YourContext : DbContext
{
public YourContext() : base("name=DefaultConnection")
{
}
public DbSet<aaaa> Aaaas { get; set; }
}
I got the same problem when trying to create a database using Code First(without database approach). The problem is that EF doesn't have enough permissions to create a database for you.
So I worked my way up using the Code First(using an existing database approach).
Steps :
Create a database in the Sql server management studio(preferably without tables).
Now back on visual studio, add a connection of the newly created database in the server explorer.
Now use the connection string of the database and add it in the app.config with a name like "Default Connection".
Now in the Context class, create a constructor for it and extend it from base class and pass the name of the connection string as a parameter.
Just like,
public class DummyContext : DbContext
{
public DummyContext() : base("name=DefaultConnection")
{
}
}
5.And now run your code and see the tables getting added to the database provided.
Run Visual Studio as Administrator, it worked for me
This error can also occur if you have multiple projects in the solution and the wrong one is set as the start-up project.
This matters because the connection string used by Update-Database comes from the start-up project, rather than the "Default project" selected in the package manager console.
(credits to masoud)
I have resolved this problem in my way.
Try connection string in this way:
<add name="MFCConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\MFC.mdf;Initial Catalog=MFC;Integrated Security=false;User ID=sa;Password=123"
providerName="System.Data.SqlClient" />
remember to set default db from master to MFC (in your case, aspnet-test-2012615153521).
Double check your connection string. When it points to non-existing database, EF tries to create tables in master database, and this error can occur.
In my case there was a typo in database name.
As the error suggests, the SQL login has no permission to create database. Permissions are granted when the login have the required roles. The role having permission to create, alter and drop database is dbCreator. Therefore it should be added to the login to solve the problem. It can be done on SQL Management Studio by right-clicking the user then go to Properties>Server Roles. I encountered the same error and resolved it by doing exactly that.
I encountered what appeared to be this error. I was running on windows and found my administrator windows user did not have administrator privileges to database.
Shut down SQL Server from ‘Services’
Open cmd window (as administrator) and run single-user mode as local admin with this command (the version of MSSQL may differ):
"C:\Program Files\Microsoft SQL Server\MSSQL14.SQLEXPRESS\MSSQL\Binn\sqlservr.exe" -m -s SQLEXPRESS
Open another cmd window (as administrator)
Open sqlcmd on that terminal with:
sqlcmd -S .\SQLEXPRESS
Now add the sysadmin role to your user:
sp_addsrvrolemember 'domain\user', 'sysadmin'
GO
Re-enable SQL Server from ‘Services’
Credit to:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/76fc84f9-437c-4e71-ba3d-3c9ae794a7c4/
Create the empty database manually.
Change the "Integrated Security" in connection string from "true" to
"false".
Be sure your user is sysadmin in your new database
Now I hope you can execute update-database successfully.
If you're running the site under IIS, you may need to set the Application Pool's Identity to an administrator.
Run Visual Studio as Administrator and put your SQL SERVER authentication login (who has the permission to create a DB) and password in the connection string, it worked for me
run this on your master database
ALTER SERVER ROLE sysadmin ADD MEMBER your-user;
GO
I'm going to add what I've had to do, as it is an amalgamation of the above.
I'm using Code First, tried using 'create-database' but got the error in the title.
Closed and re-opened (as Admin this time) - command not recognised but 'update-database' was so used that. Same error.
Here are the steps I took to resolve it:
1) Opened SQL Server Management Studio and created a database "Videos"
2) Opened Server Explorer in VS2013 (under 'View') and connected to the database.
3) Right clicked on the connection -> properties, and grabbed the connection string.
4) In the web.config I added the connection string
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=MyMachine;Initial Catalog=Videos;Integrated Security=True" providerName="System.Data.SqlClient"
/>
</connectionStrings>
5) Where I set up the context, I need to reference DefaultConnection:
using System.Data.Entity;
namespace Videos.Models
{
public class VideoDb : DbContext
{
public VideoDb()
: base("name=DefaultConnection")
{
}
public DbSet<Video> Videos { get; set; }
}
}
6) In Package Manager console run 'update-database' to create the table(s).
Remember you can use Seed() to insert values when creating, in Configuration.cs:
protected override void Seed(Videos.Models.VideoDb context)
{
context.Videos.AddOrUpdate(v => v.Title,
new Video() { Title = "MyTitle1", Length = 150 },
new Video() { Title = "MyTitle2", Length = 270 }
);
context.SaveChanges();
}
Check that the connection string is in your Web.Config. I removed that node and put it in my Web.Debug.config and this is the error I received. Moved it back to the Web.config and worked great.
Step 1: Disconnect from your local account.
Step 2: Again Connect to Server with your admin user
Step 3: Object Explorer -> Security -> Logins -> Right click on your server name -> Properties -> Server Roles -> sysadmin -> OK
Step 4: Disconnect and connect to your local login and create database.
I have no prove for my solution, just assumptions.
In my case it is caused by domain name in connection string. I have an assumption that if DNS server is not available, it is not able to connect to database and thus the Entity Framework tries to create this database. But the permission is denied, which is correct.
The solution that worked for me was to use the Entity Framework connection string that is created when I ran the database first wizard when creating the edmx file. The connection string needs the metadata file references, such as "metadata=res:///PSEDM.csdl|res:///PSEDM.ssdl|res://*/PSEDM.msl". Also, the connection string needs to be in the config of the calling application.
HT to this post for pointing me in that direction: Model First with DbContext, Fails to initialize new DataBase
For me I just close all current session including the SQL Server Management Studio and then I reopened execute the script below works fine
IF EXISTS (SELECT NAME FROM master.sys.sysdatabases WHERE NAME = 'MyDb')
DROP DATABASE mydb RESTORE DATABASE SMCOMDB FROM DISK = 'D:/mydb.bak'
I had the same problem and I tried everything available on the internet. But SSMS RUN AS ADMINISTRATOR work for me.
If you still face some issue, make sure you must have downloaded the SQL SERVER.
the reason for this error may be originate from forwarding of version dependent localdb in visual sudio 2013 to the version independent localDB in VS 2015 onwards, so
simply change your web.config file connectionStrings from (localDb)\v11.0 to (localDB)\MSSQLLocalDB and it will certainly work.
and this is a good explaination for that Version independent local DB in Visual Studio 2015
If you are using .\SQLExpress as Data Source, you can add "User Instance=True" attribute to your connection string, to fix the error mentioned in the title.
For example,
Data Source=.\\SQLExpress;Integrated Security=true;
User Instance=true;
AttachDBFilename=|DataDirectory|\app_data\Northwind.mdf;
Initial Catalog=Northwind;
User instances allow users who are not administrators on their local computers to attach and connect to SQL Server Express databases. Each instance runs under the security context of the individual user, on a one-instance-per-user basis.
Reference: MSDN Link for SQL Server Express User Instances
This is so wrong - never over-elevate your permissions (use SA) where you don't need to do so.
To create database all you need is: CREATE DATABASE, CREATE ANY DATABASE, or ALTER ANY DATABASE permission as per
documentation or the login to be a member of the dbcreator
server level role.
Next - you need to make sure that mssql service login (NT Service\MSSQLServer by default) has permission to modify the file
system in the location where you want to create your database
(usually 1 .mdf file for data pages and 1 .ldf file for database
logs).
Then make sure you know where you create your databases! EF by
default sends the laziest query possible, defining only database
name: CREATE DATABASE [db_name] and then assuming all of the rest -
applying default settings. Make sure you either change these to reflect locations mssql engine service has access to or elevate
service permissions. Either way this modification requires mssql
restart tyo apply the setting.
Finally, make sure that you connect to the mssql using that login.
If you perform an EXECUTE AS USER statement to switch your login it
will fail. This method allows only to interpersonate DB user, not
the server level login. An attemp of doing it will give you CREATE DATABASE permission denied in database 'master' error message.
To get permission to create database in your local account follow the below given steps.
Disconnect from your local account.
Again Connect to Server with Login : sa and Password : pwd(pwd given to your local login).
Object Explorer -> Security -> Logins -> Right click on your server name -> Properties -> Server Roles -> sysadmin -> OK
Disconnect and connect to your local login and create database.
P.s: For me even without connect/disconnect to server, it worked!
I had the same issue, I tried couple of other methods, but none of them worked. I just simply exit the SSMS and run it as an administrator and it worked perfectly.
The solution to this problem is as simple as eating a piece of cake.This issue generally arises when your user credentials change and SQL server is not able to identify you .No need to uninstall the existing SQL server instance .You can simply install a new instance with a new instance name . Lets say if your last instance name was 'Sqlexpress' , so this time during installation , name your instance as 'Sqlexpress1' . Also don't forget to select the mix mode (i.e Sql Server Authentication & Windows Authentication) during the installation and provide a system admin password which will be handy if such a problem occurs in future.
This solution will definitely resolve this issue. Thanks..
Permission denied is a security so you need to add a "User" permission..
Right click you database(which is .mdf file) and then properties
Go to security tab
Click Continue button
Click Add button
Click Advance button
Another window will show, then you click the "Find Now" button on the right side.
On the fields below, go to the bottom most and click the "Users". Click OK.
Click the permission "Users" that you have been created, then Check the full control checkbox.
There you go. You have now permission to your database.
Note: The connection-string in the above questions is using SQL-server authentication. So, Before taking the above step, You have to login using windows-authentication first, and then you have to give permission to the user who is using sql-server authentication. Permission like "dbcreator".
if you login with SQL server authentication and trying to give permission to the user you logged in. it shows, permission denied error.