Connect to SQL Server through PDO : DATABASE on another server - pdo

On local PC this works.
$HmsDBuser = 'test';
$HmsDBpassword = 'password';
$HmsDBserver = 'Developer,1433';
$HmsDBdatabase = 'DBNAME';
$this->db = new PDO ("sqlsrv:Server=$HmsDBserver;Database=$HmsDBdatabase","$HmsDBuser","$HmsDBpassword", array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
My Slim Framework is on Server A: 121.55.0.25
My database is on another Server B: 121.55.0.21
$HmsDBuser = 'test';
$HmsDBpassword = 'password';
$HmsDBserver = '121.55.0.21\MYSERVER\MSSQLSERVER,1433';
$HmsDBdatabase = 'DBNAME';
$this->db = new PDO ("sqlsrv:Server=$HmsDBserver;Database=$HmsDBdatabase","$HmsDBuser","$HmsDBpassword", array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
and after I connect to the database, I call function with path "product" in Slim framework.
ERROR got on Console :
angular.js:8619 GET http://121.55.0.25/product-manager_servertest/api/v1/products 404 (Not Found)

Try it like this:
$HmsDBserver = '121.55.0.21\\MYSERVER\\MSSQLSERVER,1433';
Notes:
Escaped backslashes.
No space before port.
If it doesn't work, then use just the server name, like this:
$HmsDBserver = '<server-name>,1433';

Related

Login failed for user token-identified principal when connecting via sql_driver_manager.getConnection

I am trying to connect to Azure SQL using Service Principle to create views, but it says
com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user ClientConnectionId: XXXXX-XXXX-XXXX
However, with the same SPN I was able to connect and create tables, read tables.
import adal
resource_app_id_url = "https://database.windows.net/"
service_principal_id = dbutils.secrets.get(scope = "XX", key = "XXX")
service_principal_secret = dbutils.secrets.get(scope = "XX", key = "spn-XXXX")
tenant_id = dbutils.secrets.get(scope = "XX", key = "xxId")
authority = "https://login.windows.net/" + tenant_id
azure_sql_url = "jdbc:sqlserver://xxxxxxx.windows.net"
database_name = "testDatabase"
encrypt = "true"
host_name_in_certificate = "*.database.windows.net"
context = adal.AuthenticationContext(authority)
token = context.acquire_token_with_client_credentials(resource_app_id_url, service_principal_id, service_principal_secret)
access_token = token["accessToken"]
using above code I am able to create and read tables. There is a requirement to create views so I am using sql_driver_manager to connect to Azure SQL
properties = spark._sc._gateway.jvm.java.util.Properties()
properties.setProperty("accessToken", access_token)
sql_driver_manager = spark._sc._gateway.jvm.java.sql.DriverManager
sql_con = sql_driver_manager.getConnection(azure_sql_url, properties)
query = """
create or alter view test_view as select * from dbo.test_table
"""
stmt = sql_con.createStatement()
stmt.executeUpdate(query)
stmt.close()
this is resulting in an error:
Py4JJavaError: An error occurred while calling
z:java.sql.DriverManager.getConnection. :
com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user token-identified principal. ClientConnectionId:
If I try the same with username and password instead of token, it works but I just need to use spn token for authenticating.
Working code:
sql_driver_manager = spark._sc._gateway.jvm.java.sql.DriverManager
sql_con = sql_driver_manager.getConnection(azure_sql_url, username, password)
query = """
create or alter view test_view as select * from dbo.test_table
"""
stmt = sql_con.createStatement()
stmt.executeUpdate(query)
stmt.close()
What is that I am missing, can someone help me understand the issue. Thanks.
You can not use that method since it was built to execute an update statement and return indexes.
See documentation. Use the prepare() and execute() methods.
https://learn.microsoft.com/mt-mt/sql/connect/jdbc/reference/executeupdate-method-java-lang-string?view=azuresqldb-current
#
# 5 - Upsert from stage to active table.
# Grab driver manager conn, exec sp
#
driver_manager = spark._sc._gateway.jvm.java.sql.DriverManager
connection = driver_manager.getConnection(url, user_name, password)
connection.prepareCall("exec [stage].[UpsertFactInternetSales]").execute()
connection.close()
This is sample code from an article I wrote. It calls a stored procedure to execute an UPSERT. However, any DML or DDL will work as long as it does not return a result set.

Why I'm getting an error in DataBricks connection with a SQL database?

I am trying to connect to a SQL Server but somehow i'm getting the below error when trying to connect to db from databricks using Python:
Error:java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbd.SQLServerDriver
My connection code is the next one:
jdbcHostname = "hostname"
jdbcDatabase = "databasename"
jdbcPort = port
username = 'username'
password = 'password'
jdbcUrl = "jdbc:sqlserver://{0}:{1};database={2}".format(jdbcHostname, jdbcPort, jdbcDatabase)
connectionProperties = {
"user" : username,
"password" : password,
"driver" : "com.microsoft.sqlserver.jdbd.SQLServerDriver"
}
The last code works, but when I try to execute a query I got the mentioned error coming out from the second code line from the next block:
pushdown_query = "select * from table"
df = spark.read.jdbc(url=jdbcUrl, table=pushdown_query, properties=connectionProperties)
display(df)
I tried to install different connectors but I have not been lucky with it, could you help me?

How to perform a SQL query with SQLAlchemy to later pass it into a pandas dataframe

I have followed this article set up, it all seems to work properly, but I would like now to perform a SQL query and pass the result into a pandas data frame, how could I proceed?
This is what I have now;
host_server = os.environ.get('host_server', 'localhost')
db_server_port = urllib.parse.quote_plus(str(os.environ.get('db_server_port', '5432')))
database_name = os.environ.get('database_name', 'my_data_base123')
db_username = urllib.parse.quote_plus(str(os.environ.get('db_username', 'my_user_name123')))
db_password = urllib.parse.quote_plus(str(os.environ.get('db_password', 'my_password123')))
ssl_mode = urllib.parse.quote_plus(str(os.environ.get('ssl_mode','prefer')))
DATABASE_URL = 'postgresql://{}:{}#{}:{}/{}?sslmode={}'.format(db_username, db_password, host_server, db_server_port, database_name, ssl_mode)
database = databases.Database(DATABASE_URL)
metadata = sqlalchemy.MetaData()
engine = sqlalchemy.create_engine(
DATABASE_URL, pool_size=3, max_overflow=0
)
metadata.create_all(database)
app = FastAPI(title="REST API using FastAPI PostgreSQL Async EndPoints")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
#app.on_event("startup")
async def startup():
await database.connect()
#app.on_event("shutdown")
async def shutdown():
await database.disconnect()
Trying to access the database with a SQL query:
with engine.connect() as conn:
result = conn.execute(text("select 'hello world'))
print(result.all())
as it says in the sqlalchemy documentation , but i get some errors, like:
print(result.all())
AttributeError: 'ResultProxy' object has no attribute 'all'
even if i try to access the tables of my database
with engine.connect() as conn:
result = conn.execute(text("select * FROM users"))
print(result.all())
i get the same error
It is solved, I had to upgrade SQLAlchemy
sudo pip install sqlalchemy --upgrade

Writing to a config file dynamically using PHP

Implementing a SAAS (multi-tenant) app, I have a situation where an app would need to connect to different databases based on the user who wants to login. The databases are for separate institutions. Let's say MANAGER-A for institution-A, MANAGER-B for institution-B, want to login into their various institutions.
The process I'm implementing is this: There are 3 databases involved: DEFAULT-DB, INSTITUTION-A-DB, INSTITUTION-B-DB. The DEFAULT-DB contains all the login and database credentials of each user. This means that before MANAGER-A can login to his app, what happens is that, first, he will be logged in into the DEFAULT-DB, if successful, his details would be fetched and logged and set as the parameter of the config.php file. This means that connection will be dynamic based on the params fetched and passed by the DEFAULT-DB. My questions are these:
How do I write these params dynamically to the config.php file?
Secondly, I'm open to experts advise if my implementation is not the best.
Config.php file
<?php
unset($CFG);
global $CFG;
$CFG = new stdClass();
$CFG->dbtype = 'mysqli';
$CFG->dblibrary = 'native';
$CFG->dbhost = 'localhost';
$CFG->dbname = 'mydb';
$CFG->dbuser = 'root';
$CFG->dbpass = '';
$CFG->prefix = 'my_';
$CFG->dboptions = array (
'dbpersist' => 0,
'dbport' => '',
'dbsocket' => '1',
'dbcollation' => 'utf8mb4_unicode_ci',
);
$CFG->wwwroot = 'http://localhost:8888/myapp';
$CFG->dataroot = '/Applications/MAMP/data/myapp_data';
$CFG->admin = 'admin';
$CFG->directorypermissions = 0777;
require_once(dirname(__FILE__) . '/lib/setup.php');
This is Moodle. I have tried IOMAD, it is a great app but does not address my need.
That is a bad solution, IMHO. When you rewrite the configuration file, what happens when the next request comes in that loads that file? They will load the wrong configuration.
I would create two additional configuration files: config_inst_a.php and config_inst_b.php. Then set a session variable when the user logs in that contains the settings file name to load. You can then redefine the database information variables in the additional settings files. If the session variable has a filename in it, load that file AFTER the default config and the database connection values will be replaced.
Added sample code:
Really, really brief:
// Log in user here, and get info about what user company..
$session_start();
$_SESSION['User_ConfigFile'] = 'settings'.$userCompany.'.php';
// More code, or page redirect, or whatever, but the below goes on every page AFTER the default DB is included:
$session_start();
require_once($_SESSION['User_ConfigFile']);
If it helps somebody, my solution, not in production yet, but for now it works like a charm.
if ($_SERVER['SERVER_NAME'] == 'institutionA.mydomain.com') {
$CFG->dbname = 'institutionA'; // database name, eg moodle
$CFG->dbuser = 'user_institutionA'; // your database username
$CFG->wwwroot = 'https://institutionA.mydomain.com';
$CFG->dataroot = 'dataroot_institutionA';
//
$CFG->some_custom_data = 'my_institutiona_data';
} else
if ($_SERVER['SERVER_NAME'] == 'institutionB.mydomain.com') {
$CFG->dbname = 'institutionB'; // database name, eg moodle
$CFG->dbuser = 'user_institutionB'; // your database username
$CFG->wwwroot = 'https://institutionB.mydomain.com';
$CFG->dataroot = 'dataroot_institutionB';
//
$CFG->some_custom_data = 'my_institutionB_data';
} else {
...... anything you need in this case
}

Writing a Groovy Script to execute this command to PostgresDB

I currently am using SOAPUI 4.0 Pro to hit a Postgresdb on a specific host. I have modified my properties file to include port, username, and password and name of database. Here is my query below:
SELECT
eis_entity.local_id,
eis_trait_instance_history.trait_value,
eis_identifier_domain.identifier,
eis_identifier_domain.label
FROM
public.eis_entity,
public.eis_trait_instance_history,
public.eis_version_label,
public.eis_identifier_domain
WHERE eis_identifier_domain.eis_identifier_domain_key = eis_entity.eis_identifier_domain_key
AND eis_entity.eis_entity_key=eis_version_label.eis_entity_key
AND eis_version_label.eis_version_label_key=eis_trait_instance_history.eis_version_label_key
AND eis_trait_instance_history.trait_value='<name of patient>';
How would I create a groovy script for the query above?
Assuming you can pick up Groovy SQL basics and have a handle on a sql instance...
sql = Sql.newInstance(...)
def List eisEntityList = sql.rows("""
SELECT eis_entity.local_id,
eis_trait_instance_history.trait_value,
eis_identifier_domain.identifier,
eis_identifier_domain.label
FROM public.eis_entity,
public.eis_trait_instance_history,
public.eis_version_label,
public.eis_identifier_domain
WHERE eis_identifier_domain.eis_identifier_domain_key = eis_entity.eis_identifier_domain_key
AND eis_entity.eis_entity_key = eis_version_label.eis_entity_key
AND eis_version_label.eis_version_label_key = eis_trait_instance_history.eis_version_label_key
AND eis_trait_instance_history.trait_value = ''
""")
if (eisEntityList?.size() > 0) {
eisEntityList.each {
// do something with each item...
}
}