I need an R script that allows me to connect to an Oracle DB without having to install anything needing admin powers, and preferrably nothing at all apart from package downloads. In python the following code works, I believe because it uses the cx_Oracle module as a portable driver. What would be a good R alternative?
import pandas as pd
import sqlalchemy
import sys
host = "xxx.intra"
database = "mydb"
user = "usr"
password = "pw"
def get_oracle_engine(host, database, user, password):
return sqlalchemy.create_engine("oracle+cx_oracle://{user}:{password}#{host}:1521/?service_name={database}".format(host=host, database=database, user=user, password=password))
engine=get_oracle_engine(host, database, user, password)
pd.read_sql_table("mytable", engine, schema= mydb,index.cols="id1")
I managed to install ROracle using the CRAN instructions but I keep getting the ORA-12154 TNS: cound not resolve the connect identifier specified when using:
library(ROracle)
con= DBI::dbconnect(dbDriver("Oracle"), user= user, password=password, host=host, dbname=database, port="1521")
By the way dbDriver("Oracle") returns
Driver name : Oracle (OCI)
Driver version: 1.3-1
Client version: 12.1.0.2.0
Try code like:
library(DBI)
library(ROracle)
drv <- Oracle()
con <- dbConnect(drv, 'cj', 'welcome', 'localhost:1521/orclpdb1')
dbGetQuery(con,"select count(*) from dual")
The connect string components are related to the {host}:1521/?service_name values you used with SQLAlchemy. Use a TNS alias or Easy Connect String, the same as other C based Oracle drivers, e.g. https://cx-oracle.readthedocs.io/en/latest/user_guide/connection_handling.html#connection-strings
The current ROracle code is at https://www.oracle.com/database/technologies/roracle-downloads.html There are some packaging glitches with uploading to CRAN and the CRAN maintainers haven't been responsive about resolving them.
ROracle still needs Oracle Client libraries such as from Oracle Instant Client.
Related
I need to check oracle connectivity using python script.
My oracle connection string is in below format.
jdbc:oracle:thin:#ldap://ovd.mycomp.com:38901/cn=Oraclecontext,o=eus,dc=mycomp,dc=com/pidev ldap://ovd- mwdc.mycomp.com:38901/cn=Oraclecontext,o=eus,dc=mycomp,dc=com/pidev.
I tried https://dbajonblog.wordpress.com/2019/12/18/python-and-cx_oracle-for-oracle-database-connections/ but that did not help.
Could you please help me.
Thanks in advance.
The general cx_Oracle documentation on working with JDBC and Oracle SQL Developer Connection Strings has some info however if you're using LDAP you'll need to do some extra configuration. See https://stackoverflow.com/a/32151099/4799035 and https://github.com/oracle/node-oracledb/issues/1212#issuecomment-591940440 The steps are the same for cx_Oracle. Also see Connect to DB using LDAP with python cx_Oracle
I created following script using cx_oracle, which works fine.
only restriction is the dns name should be TNS entry.
Script:
import cx_Oracle
import sys
from botocore.exceptions import ClientError
connection = None
def isOracleHealthy(dbname, username, password, dns, log):
try:
sys.stderr.write(dns)
connection=cx_Oracle.connect("{}/{}#{}".format(username, password, dns))
cur=connection.cursor()
for result in cur.execute("SELECT * FROM dual"):
log.info(result)
return True
except Exception as e:
sys.stderr.write(dbname+' Oracle health check failed.\n')
log.error(dbname+' Oracle health check failed.')
return False
I am using a Python script to connect to a SQL Server database:
import pyodbc
import pandas
server = 'SQL'
database = 'DB_TEST'
username = 'USER'
password = 'My password'
sql='''
SELECT *
FROM [DB_TEST].[dbo].[test]
'''
cnxn = pyodbc.connect('DRIVER=SQL Server;SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
data = pandas.read_sql(sql,cnxn)
cnxn.close()
The script is launched everyday by an automatisation tools so there is no physical user.
The issue is how to replace the password field by a secure method?
The automated script is still ran by a windows user. Add this windows user to the SQL-Server users and give it the appropriate permissions, so you can use:
import pyodbc
import pandas
server = 'SQL'
database = 'DB_TEST'
sql='''
SELECT *
FROM [DB_TEST].[dbo].[test]
'''
cnxn = pyodbc.connect(
f'DRIVER=SQL Server;SERVER={server};DATABASE={database};Trusted_Connection=True;')
data = pandas.read_sql(sql,cnxn)
cnxn.close()
I am also interested in secure coding using Python .I did my own research to figure out available options, I would recommend reviewing this post as it summarize it all. Check on the listed options, and apply the one suits you better.
I've spent a few days trying to determine how to connect to a Sybase IQ database through Python 3.6. I've tried pyodbc and pymssql, to no avail. Below are two code snippets that I've been working on, which don't seem to work, no matter what I try.
pyodbc:
conn = pyodbc.connect(driver='{SQL Server Native Client 11.0}',
server=server,
database=database,
port=port,
uid=user,
pwd=pwd)
pymssql:
conn = pymssql.connect(server=server,
port=port,
user=user,
password=pwd,
database=database)
I've also read that FreeTds could be the solution for connecting to a Sybase IQ database; I thought it was installed as part of the pymssql database, but I can't seem to figure out how to leverage it. Any help would be greatly appreciated!
EDIT: I am aware that sqlanydb exists; however, this package makes me downgrade to Python 2.7. My stack is 3.6 and I'd like to not have to move off of that.
After some time, I was able to resolve this issue (On Windows). First, install SQL Anywhere 17 driver. Once that's been installed, in the Windows ODBC Data Sources window, set up a connection using the SQL Anywhere 17, and your Sybase IQ credentials. Once that has been configured and successfully tested, you can use the below code snippet to connect:
from sqlalchemy import create_engine
sybase_connection_string = "sqlalchemy_sqlany://{user}:{pwd}#{host}:{port}/{db}".\
format(user=user, pwd=pwd, host=host, port=port, db=database)
engine = create_engine(sybase_connection_string)
return engine.connect()
I believe you will need the sqlalchemy_sqlany module installed via pip, as well as sqlalchemy.
Alternative use jconn4 or jconn3 driver.
Example of connection:
import jaydebeapi
jar_path = "/drive/jconn4.jar"
driver_name = "com.sybase.jdbc4.jdbc.SybDriver"
_ipad = '1.1.1.1'
_port='2638'
con_prop= { "user": 'user', "password": 'pwd'}
connection_url = f"jdbc:sybase:Tds:{_ipad}:{_port}"
conn= jaydebeapi.connect(driver_name, connection_url,con_prop, jar_path)
You can use jconn4.jar to connect to Sybase IQ.
I was able to connect with SAP IQ/16.1.080.1841
To get jconn4.jar, use dbeaver and connect with sybase batabase. Dbeaver will download this jar, which you can use. You can download community edition from official site https://dbeaver.io/
This will require JAVA, to get this running. I used JDK 1.8.0_181
Install jaydebeapi for your python with pip install jaydebeapi.
I used python 3.11.0 and jaydebeapi==1.2.3
Once you have this, connect like below:
import jaydebeapi
jconn4_file_path = '<path/to/jconn4.jar>'
driver = 'com.sybase.jdbc4.jdbc.SybDriver'
db_server = '<server hostname>'
db_port = <port>
db_user = '<database username>'
db_password = '<database password>'
db_name = '<database name>'
connection_string = f'jdbc:sybase:Tds:{db_server}:{db_port}?ServiceName={db_name}'
connection = jaydebeapi.connect(
driver,
connection_string,
[db_user, db_pass],
jconn4_file_path
)
I've been trying for some days to connect my python 3 script to PostgresSQL database(psycopg2) in Heroku, without Django.
I found some article and related questions, but I had to invest a lot of time to get something that I thought should be very straightforward, even for a newbie like me.
I eventually made it work somehow but hopefully posting the question (and answer) will help other people to achieve it faster.
Of course, if anybody has a better way, please share it.
As I said, I had a python script that I wanted to make it run from the cloud using Heroku. No Django involved (just a script/scraper).
Articles that I found helpful at the beginning, even if they were not enough:
Running Python Background Jobs with Heroku
Simple twitter-bot with Python, Tweepy and Heroku
Main steps:
1. Procfile
Procfile has to be:
worker: python3 folder/subfolder/myscript.py
2. Heroku add-on
Add-on Heroku Postgres :: Database has to be added to the appropriate personal app in the heroku account.
To make sure this was properly set, this was quite helpful.
3. Python script with db connection
Finally, to create the connection in my python script myscript.py, I took this article as a reference and adapted it to Python 3:
import psycopg2
import urllib.parse as urlparse
import os
url = urlparse.urlparse(os.environ['DATABASE_URL'])
dbname = url.path[1:]
user = url.username
password = url.password
host = url.hostname
port = url.port
con = psycopg2.connect(
dbname=dbname,
user=user,
password=password,
host=host,
port=port
)
To create a new database, this SO question explains it. Key line is:
con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
You can do it using the SQLALCHEMY library.
First, you need to install the SQLALCHEMY library using pip, if you don't have pip on your computer install, you will know-how using a simple google search
pip install sqlalchemy
Here is the code snippet that do what you want:
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
import os
# Put your URL in an environment variable and connect.
engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))
# Some variables you need.
var1 = 12
var2 = "Einstein"
# Execute statements
db.execute("SELECT id, username FROM users WHERE id=:id, username=:username"\
,{"id": var1, "username": var2}).fetchall()
# Don't forget to commit if you did an insertion,etc...
db.commit()
I wasn't able to parse the DATABASE_URL provided by Heroku with the urllib.parse as suggested above, but the following worked for me:
The URL I retrieved from Heroku was in the format:
postgres://username:password#host:port/database
for example:
postgres://jticiuimwernbk:ff78903549d4c6ec13a53a8ffefcd201b937d54c35d976
#ec2-52-123-182-987.compute-1.amazonaws.com:5432/dbsd4fdf6c1awq
So I manually dissected it as follows:
user = 'jticiuimwernbk'
password = 'ff78903549d4c6ec13a53a8ffefcd201b937d54c35d976'
host = 'ec2-52-123-182-987.compute-1.amazonaws.com'
port = '5432'
database = 'dbsd4fdf6c1awq'
#Then created the connection using the above:
con = psycopg2.connect(database=database,
user=user,
password=password,
host=host,
port=port)
# and now I was able to perform queries:
cur = conn.cursor()
results = cur.execute("<some SQL query>;").fetchall()
cur.close()
conn.close()
With JDBC, we can use the following syntax to connect to an Oracle database over an LDAP connection:
jdbc:oracle:thin:#ldap://host:1234/service_name,cn=OracleContext,dc=org,dc=com
How can I connect over LDAP using cx_oracle?
I ended up going with jaydebeapi.
import pandas as pd
import jaydebeapi
import jpype
import os
import sys
def run(f_name,command,username,pw ):
jar='ojdbc8.jar'
args = '-Djava.class.path=%s' % jar
jvm_path = jpype.getDefaultJVMPath()
jpype.startJVM(jvm_path, args)
con = jaydebeapi.connect("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:#ldap://server.prod.company.com:3060/service,cn=OracleContext,dc=prod,dc=company,dc=com",[username, pw], jar)
try:
df= pd.read_sql(command,con)
df.to_excel(f_name)
print(df)
except Exception as e:
print(e)
finally:
con.close()
def Run_Program(myvars):
os.chdir(sys._MEIPASS)
f_name = myvars.MyFileName
command = myvars.plainTextEdit_CSVString.toPlainText()
username = myvars.lineEdit_UserName.text()
pw = myvars.lineEdit_Password.text()
run(f_name,command,username,pw )
Saving the ojdbc8.jar file from Oracle Client in the same folder and specifying the location in the code. And also downgrading the module JPype1 to JPype1==0.6.3 (its installed as a requirement for jaydebeapi )
This worked well for packaging using pyinstaller so that it could be shared. (i created a pyqt5 UI for user to use.
Here are my two cents using Python 3.7 and cx_Oracle v.8.2.0 on Win 10.
I wanted to issue queries to an Oracle database using Python, and what I already had was :
a username (or schema)
a password
a JDBC connection string that looked like:
jdbc:oracle:thin:#ldap://[LDAPHostname1]:[LDAPPort1]/[ServiceName],[DomainContext] ldap://[LDAPHostname2]:[LDAPPort2]/[ServiceName],[DomainContext]
where the [DomainContext] was of the form cn=OracleContext,dc=foo,dc=bar
First, you have to install cx_Oracle by following the Oracle documentation.
Note that:
cx_Oracle requires a series of library files that are part of the Oracle Instant Client "Basic" or "Basic Light" package (available here). Let's say we unzip the package under C:\path\to\instant_client_xx_yy
Depending on the platform you're on, some other requirements are to be filled (like installing some Visual Studio redistributable on Windows)
For the LDAP part, there are two configuration files that are required:
sqlnet.ora : This is the profile configuration file for Oracle, but mine was simply containing :
NAMES.DIRECTORY_PATH = (LDAP)
It tells the library to resolve names using LDAP only.
ldap.ora : This file tells where to look for when resolving names using LDAP. I knew I was accessing two OID servers, so mine was of the form :
DIRECTORY_SERVERS=([LDAPHostname1]:[LDAPPort1], [LDAPHostname2]:[LDAPPort2])
DEFAULT_ADMIN_CONTEXT="dc=foo,dc=bar"
DIRECTORY_SERVER_TYPE=oid
Important Note : I had to remove the cn=OracleContext from the DEFAULT_ADMIN_CONTEXT entry in order to make the name resolution work
Let's say those two files were saved under C:\path\to\conf
And now comes the Python part. I used the cx_Oracle.init_oracle_client() method in order to point to the library and configuration files. (Note that there are other ways to give cx_Oracle access to those files, like setting environment variables or putting those in predefined places. This is explained under the install guide)
Here is a little sample code:
import cx_Oracle
# username and password retrieved here
cx_Oracle.init_oracle_client(lib_dir=r'C:\path\to\instant_client_xx_yy', config_dir=r'C:\path\to\conf')
try:
with cx_Oracle.connect(user=username, password=password, dsn='[ServiceName]') as connection:
cursor = connection.cursor()
cursor.execute('SELECT * FROM ALL_TAB_COLUMNS')
# Outputs tables and columns accessible by the user
for row in cursor:
print(row[1], '-', row[2])
cursor.close()
except cx_Oracle.DatabaseError as e:
print("Oracle Error", e)
The short answer is that you use an ldap.ora configuration file and specify that it is to be used in your sqlnet.ora configuration file. Although this link talks about creating a database link and not directly connecting, the same principle applies and you can connect using any of the services referenced in your LDAP server.
http://technologydribble.info/2015/02/10/how-to-create-an-oracle-database-link-using-ldap-authentication/
Some more official documentation on how it works can be found here:
https://docs.oracle.com/cd/B28359_01/network.111/b28317/ldap.htm