Firebird connection on a local database impossible within a Python script - python

I can connect to my Firebird database using Firebird ISQL Tool (Firebird 3.0.4) with the following command:
connect "C:\Documents\database.db" user 'USER' password 'PASSWORD';
When I want to do it in a Python script (Python v3.7.7 on a Windows10 64 bits), in a virtual environment including fdb v2.0.1 or even firebirdsql v1.1.3, I can't and I systematically get an error.
import fdb
con = fdb.connect(database="C:\Documents\database.db", user='USER' password='PASSWORD'')
DatabaseError: ('Error while connecting to database:\n- SQLCODE:
-902\n- Unable to complete network request to host "xnet://Global\FIREBIRD".', -902, 335544721)
or
con = fdb.connect(host='localhost', database="D:\Documents\database.db", user= 'USER' password= 'PASSWORD'')
DatabaseError: ('Error while connecting to database:\n- SQLCODE:
-902\n- Unable to complete network request to host "localhost".\n- Failed to establish a connection.', -902, 335544721)
or
con = fdb.connect(dsn="localhost:C:\Documents\database.db", user='USER' password='PASSWORD'')
DatabaseError: ('Error while connecting to database:\n- SQLCODE:
-902\n- Unable to complete network request to host "localhost".\n- Failed to establish a connection.', -902, 335544721)
or
import firebirdsql
con = firebirdsql.connect(host='localhost', database="D:\Documents\database.db", user='USER' password='PASSWORD'')
If you have any idea you are welcome as I am stuck.

The error indicates that the fbclient.dll loaded by FDB does not provide Firebird Embedded, and that you don't have Firebird Server running on your machine.
To address this you must either:
Start Firebird Server (by starting its service or running firebird -a)
If you want to use Firebird Embedded instead of Firebird Server, point FDB to a fbclient.dll that provides Firebird Embedded
Point 2 can be done in several ways. In my answer I'm assuming use of Firebird 3 installed in C:\Program Files\Firebird\Firebird-3.0.5.33220-0_x64. Since Firebird 3, a normal Firebird Server install also provides Firebird Embedded. To point to a Firebird Embedded, you can do the following:
Add the Firebird installation directory to the PATH environment variable (make sure it is listed before %SystemRoot\System32/C:\Windows\System32). On a normal Firebird installation, the fbclient.dll without Firebird Embedded is installed in the System32 folder, and if that gets loaded, you can't use Firebird Embedded.
Use fdb.load_api to load the client library:
fdb.load_api('C:/Program Files/Firebird/Firebird-3.0.5.33220-0_x64/fbclient.dll')
This needs to be done before the first use of fdb.connect, otherwise the library found through the normal search path will be used
Specify the client library using the fb_library_name connection property:
con = fdb.connect(dsn='C:/path/to/yourdatabase.fdb', user='sysdba', password='masterkey',
fb_library_name='C:/Program Files/Firebird/Firebird-3.0.5.33220-0_x64/fbclient.dll')
This property needs to be specified on the first connection made using FDB. Although the existence of the property would suggest this is 'per connection', FDB will always use the first client library loaded (in essence, it works as if you called load_api just before the connect).
If you're using Firebird 2.5 or earlier, you will need to download the specific Firebird 2.5 Embedded package, and point to its fbembed.dll instead of fbclient.dll. For Firebird 2.5 Embedded, adding its location to the path will not work unless you rename or copy its fbembed.dll to fbclient.dll.

Related

Connect to Oracle database using python from a Linux server (lxv)

In my local machine
I have created a script in python that retrieves data from an Oracle database.
The connection to the DB is done using cx_Oracle:
con = cx_Oracle.connect (username, password, dbService)
When using SQL developer the connection is established using custom JDBC.
Replicate procedure on a Linux server.
I have created a python virtual environment with cx-Oracle pip installed in it.
I have Oracle Client 19.3.0 installed in the server, and the folder instantclient is in place.
When I try to execute the python script as is I get the following error.
cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle
Client library:
DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". See https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html for help
I assumed that the problem was the Oracle path which is not the one that python expected. So, I added this extra line of code pin-pointing the path where the Oracle libraries are located.
cx_Oracle.init_oracle_client(lib_dir=r"/apps/oracle/product/19.3.0/lib")
This leads to a different error:
cx_Oracle.DatabaseError: Error while trying to retrieve text for error
ORA-01804
Any clues?
The answer to my question was indicated by the ORA-1804 message.
According to the Oracle initialization doc: https://cx-oracle.readthedocs.io/en/latest/user_guide/initialization.html#usinginitoracleclient
Note if you set lib_dir on Linux and related platforms, you must still
have configured the system library search path to include that
directory before starting Python.
On any operating system, if you set
lib_dir to the library directory of a full database or full client
installation, you will need to have previously set the Oracle
environment, for example by setting the ORACLE_HOME environment
variable. Otherwise you will get errors like ORA-1804. You should set
this, and other Oracle environment variables, before starting Python,
as shown in Oracle
Even though defining the ORACLE_HOME should be done before starting Python (according to Oracle documentation) it is possible to do so by modifying the python script itself. So before the oracle client initialization command the following commands had to be added:
import os
# Setup Oracle paths
os.environ["ORACLE_HOME"] = '/apps/oracle/product/19.3.0'
os.environ["ORACLE_BASE"] = '/apps/oracle'
os.environ["ORACLE_SID"] = 'orcl'
os.environ["LD_LIBRARY_PATH"] = '/apps/oracle/product/19.3.0/lib'
import cx_Oracle
# Initialize Oracle client
cx_Oracle.init_oracle_client(lib_dir=r"/apps/oracle/product/19.3.0/lib")
The cx_Oracle initialization doc points out that on Linux init_oracle_client() doesn't really do what you think it does. You must still set the system library search path to include the Oracle libraries before the Python process starts.
Do I understand correctly that the machine with Python has both the DB installed and Instant Client??
If you do want Python to use the Instant Client libraries, then set LD_LIBRARY_PATH to its location and do not set ORACLE_HOME.
If you have a full Oracle DB installation on the machine with Python, then you can delete Instant Client. You need to set ORACLE_HOME, LD_LIBRARY_PATH and whatever else is needed before starting Python - in general run source /usr/local/bin/oraenv. This should set the system library search path to include /apps/oracle/product/19.3.0/lib . A code snippet like this (untested) one may help: export ORACLE_SID=ORCLCDB;set ORAENV_ASK=NO; source /usr/local/bin/oraenv. Make sure the Python process has read access to the ORACLE_HOME directory.
The cx_Oracle installation guide discusses all this.

Error connecting to local oracle database with cx_Oracle in Jupyter

I want to connect to local database with cx_Oracle but it throws an error:
DatabaseError: DPI-1047: 64-bit Oracle Client library cannot be loaded: "libclntsh.so: cannot open shared object file: No such file or directory". See https://oracle.github.io/odpi/doc/installation.html#linux for help
I can connect to database with sqlplus and SQL Developer, but it doesnt work with Python cx_Oracle in Jupyter.
import cx_Oracle
host = 'localhost'
port = 1521
SID = 'xe'
dsn_tns = cx_Oracle.makedsn(host, port, SID)
connection = cx_Oracle.connect('user', 'passwd', dsn_tns)
Is it possible I messed sth. with environment variables or client installation?
echo ${ORACLE_HOME};
/u01/app/oracle/product/11.2.0/xe
echo ${LD_LIBRARY_PATH};
/usr/lib/oracle/12.2/client64/lib
I installed client in /usr/lib/oracle/12.2/client64/lib
You may as well update cx_Oracle. The DPI-1047 message is using text that was updated in recent versions. This won't actually solve your problem
Keep it clean. Don't set ORACLE_HOME if you are using Oracle Instant Client.
I suspect your environment variables aren't being propagated down to cx_Oracle.
With a 64-bit XE, you shouldn't need to install Instant Client in your case (because your cx_Oracle message tells me it is 64-bit because the error is looking for a 64-bit Oracle client). cx_Oracle can use the DB libraries.
Once you sort out your library search path issue, you will then hit a problem with your connection string. You are trying to use an old SID construct, but should use a Service Name. It needs to be set like:
sn = 'xe'
dsn_tns = cx_Oracle.makedsn(host, port, service_name=sn)
The cx_Oracle documentation covers installation and also has a User Guide section that is worth reviewing https://cx-oracle.readthedocs.io/en/latest/index.html

pyodbc fails to connect to database, but IBM data studio connects with same credentials

I'm trying to connect to a database on an IBM machine, and I can connect just fine via the IBM desktop client "IBM Data Studio." However, when I try to connect with pyodbc it fails to connect. I've received a series of errors but it seems the main response is along the lines of the following
pyodbc.OperationalError: ('08001', u'[08001] [Microsoft][ODBC SQL Server Driver]
[TCP/IP Sockets]SQL Server does not exist or access denied. (17)
(SQLDriverConnect); [08001] [Microsoft][ODBC SQL Server Driver][TCP/IP Sockets]ConnectionOpen (
Connect()). (10061); [08001] [Microsoft][ODBC SQL Server Driver]Invalid connection string attribute (0)')
My code follows:
import pyodbc
# Specifying the ODBC driver, server name, database, etc. directly
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=*****; PORT=50000;DATABASE=****;UID=***;PWD=***')
# Create a cursor from the connection
cursor = cnxn.cursor()
cnxn.close()
I am working on a Windows machine.
You cannot use an ODBC Driver for Microsoft SQL Server, to connect to an instance of IBM DB2 (nor to any DBMS other than Microsoft SQL Server).
You need an ODBC Driver for IBM DB2 for this connection, such as those from my employer.
You could also use an ODBC-to-JDBC Bridge Driver, in combination with a JDBC Driver for IBM DB2, such as JTOpen (open source, from IBM).
Just because a jdbc connection from Data-Studio is working, it does not mean that your pyodbc will connect to Db2. pyodbc does not use jdbc, instead it will use the CLI/ODBC interface to Db2 which gets implemented by a suitable driver.
To use Db2 from pyodbc on Windows, ensure you first have either a Db2-client installed on Windows, or a Db2-server installed installed on Windows.
There are many kinds of Db2-clients. Much depends on the operating-system that runs your Db2-server (Z/OS, i-Series, Linux, Unix, Windows), and what kind of activities you want to perform on the client (developing, administering/monitoring, querying, or all three).
For some target platforms there are non-IBM drivers, but I won't discuss those.
In python, you can choose to connect to a database either with a DSN (Data Source Name) (usually this involves a shorter connection string)
or without a DSN (longer connection string containing all the details).
When learning, it may be easier to get Microsoft Windows to do most of the initial work with odbcad32.
This is most easy if the Db2-client is already configured to access one or more Db2-databases . The prereq is that the driver supports CLI/ODBC.
To define a DSN (either a system-DSN or a user-DSN) use the Microsoft odbcad32 tool to point to your Db2 database and verify connectivity.
If the Db2-server runs on Z/OS or i-Series, special licensing requirements may apply depending on whether you are directly connecting to the target Db2-server or whether you are using a Db2-connect gateway.
Take a note of the exact DRIVER string inside odbcad32 for the Db2-database, including case and spaces because you will need that in your python code.
For example, that driver name might look like 'IBM DB2ODBC DRIVER - DB2COPY1' if you have a local Db2-server installed on Windows (such as the free Db2-Express-C).
Verify that the connection to the Db2-database is successful inside odbcad32. That is crucial.
When odbcad32 succeeds to connect then pyodbc will succeed to connect usually.
In your python code, your connection-string can either use the DSN or explicitly quote the DRIVER/SERVER/PORT/DATABASE/UID/PWD, along with any other required settings on the connection string.
Remember also that you don't have to use pyodbc. There are other options for python to interact with Db2-Servers. Make an informed choice and do your research.
You can also use the IBM supplied module "ibm_db" or the DBI interface module "ibm_db_api", or if you are using an object relational mapper you can use the SQLAlchemy adapter (ibm_db_sa), or you can use django framework.
Read all about that in the Db2 documentation here.
https://www.ibm.com/support/knowledgecenter/en/SSEPGG_10.5.0/com.ibm.swg.im.dbclient.python.doc/doc/c0054366.html
I have solved the problem! The issue was that I was missing the "iSeries Access ODBC Driver". I don't think it's available online, although I could be wrong, I had to have our database guy help install it. Now I can connect through both the ibm_db and pyodbc libraries, after setting up my DSN under "odbcad32.exe." This took a while to solve but mostly because of the lack of informative documentation from IBM. Hopefully, this helps anyone in the same situation.

pyodbc error: Data source name not found (Win8)

I am trying to connect using the pyodbc capability with the following connection string:
DRIVER={SQL Native Client}.
Getting the following error:
Error connecting to database: [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)
Main issue is that on my machine everything works like a charm, while execution on other machines return the error above.
Many thanks!
That is presumably because your connection string specifies some Windows datasource (a datasource is effectively an os-level alias) which exists on your machine, but does not exist on the other machines. You probably need to define the datasource on the other machines.
As Flipper suggests, first check out your connection string to determine what the name of the datasource is. Then check on your machine how that datasource is configured, then create and configure similar datasources on the other machines.
maybe check out the info and links on this ms dev-net page on datasources:
ODBC Data Source Administrator
All Windows installs include a copy of the older "SQL Server" ODBC driver
Driver={SQL Server}
so that should be available on any Windows machine for both 32-bit and 64-bit applications.
More recent versions of SQL Server have introduced their own client software to support their latest features. Drivers like
Driver={SQL Native Client} (9.0, for SQL Server 2005)
Driver={SQL Server Native Client 10.0} (for SQL Server 2008)
Driver={SQL Server Native Client 11.0} (for SQL Server 2012/2014)
will only work if the machine has the required SQL Server client software installed. (It can be downloaded and installed separately for machines that don't run SQL Server itself, usually as part of a "SQL Server Feature Pack".)
So, if you really need the more advanced features of the later "Native Client" ODBC driver then you will have to ensure that it gets installed on the other machines. Otherwise, just stick with the older "SQL Server" driver.

Install MYSQLdb python module without MYSQL local install

I'm trying to install MYSQLdb on a windows client. The goal is, from the Windows client, run a python script that connects to a MySQL server on a LINUX client. Looking at the setup code (and based on the errors I am getting when I try to run setup.py for mysqldb, it appears that I have to have my own version of MySQL on the windows box. Is there a way (perhaps another module) that will let me accomplish this? I need to have people on multiple boxes run a script that will interact with a MySQL database on a central server.
you could use a pure python implementation of the mysql client like
pymysql
(can be used as a dropin-replacement for MySQLdb by calling pymysql.install_as_MySQLdb())
MySql-Connector
You don't need the entire MySQL database server, only the MySQL client libraries.
It's been a long time since I wrote python db code for windows...but I think something like this should still work.
If you're running the client only on windows machines, install the pywin32 package. This should have an odbc module in it.
Using the windows control / management tools, create an odbc entry for either the user or the system. In that entry, you'll give the connection parameter set a unique name, then select the driver (in this case MySQL), and populate the connection parameters (e.g. host name, etc.) See PyWin32 Documentation for some notes on the odbc module in pywin32.
Also, see this post: Common ways to connect to odbc from python on windows.

Categories

Resources