Cannot connect to DB2 from Groovy - sql

I’m trying to open an SQL instance within a driver which uses the DB2Driver from IBM.
The interesting part is that when I include:
def DB2Driver = new DB2Driver()
That initializes just fine.
But when I do
Sql.newInstance(info.getHost(), info.getConnectionMetaData().getParameterValue('username'), info.getConnectionMetaData().getParameterValue('password'), info.getConnectionMetaData().getParameterValue('driverClass'))
Or
Sql.newInstance(info.getHost(), info.getConnectionMetaData().getParameterValue('username'), info.getConnectionMetaData().getParameterValue('password'), 'com.ibm.db2.jcc.DB2Driver')
It will fail to open a SQL connection, saying that a suitable driver isn't found. How can I get the connection to DB2 to open?

Assuming that you are using a groovy script with #Grab and #Grapes annotations, you probably need configure Grape for JDBC drivers:
Because of the way JDBC drivers are loaded, you’ll need to configure Grape to attach JDBC driver dependencies to the system class loader
In groovy.sql.Sql the JDBC DriverManager is used to get a connection: DriverManager.getConnection(). Since it needs the driver depencencies attached to the system class loader, you need to do it with #GrabConfig.
For example, this script
#Grapes([
#Grab(group='org.hsqldb', module='hsqldb', version='2.3.2'),
])
import groovy.sql.Sql
def sql = Sql.newInstance('jdbc:hsqldb:mem:testdb', 'sa', '', 'org.hsqldb.jdbcDriver')
println 'SQL connection ready'
fails with the exception java.sql.SQLException: No suitable driver found for jdbc:hsqldb:mem:testdb, but with
#Grapes([
#Grab(group='org.hsqldb', module='hsqldb', version='2.3.2'),
#GrabConfig(systemClassLoader=true)
])
it works perfectly.

Related

Intermittent 500 internal server error in images after adding isolation_level to a flask-sqlalchemy app on apache mod_wsgi server

I am using Apache mod_wsgi in a flask-sqlalchemy, marshamllow application, connecting to a remote ms sql database using pyodbc, recently I was asked to add isolation_level 'SNAPSHOT' and I did that using apply_driver_hacks
class SQLiteAlchemy(SQLAlchemy):
def apply_driver_hacks(self, app, info, options):
options.update({
'isolation_level': 'SNAPSHOT',
})
super(SQLiteAlchemy, self).apply_driver_hacks(app, info, options)
the project is built to access image blob data from a ms sql server and display on a webpage, soon after adding the isolation level I see internal error generated for every few images, doing a ctrl+f5 displays the image but then there are other images not being displayed and this is in the error log
mod_wsgi (pid=10694): Exception occurred processing WSGI script
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Transaction failed in database 'testdb' because the statement was run under snapshot isolation but the transaction did not start in snapshot isolation. You cannot change the isolation level of the transaction to snapshot after the transaction has started unless the transaction was originally started under snapshot isolation level. (3951) (SQLExecDirectW)")
edited to add code below:
how would I do that with flask-sqlalchmey when not using create-engine
my app.py file
app = Flask(__name__)
app.config.from_object('config.ProductionConfig')
db.init_app(app)
ma.init_app(app)
my model.py file
class SQLiteAlchemy(SQLAlchemy):
def apply_driver_hacks(self, app, info, options):
options.update({
'isolation_level': 'SNAPSHOT',
})
super(SQLiteAlchemy, self).apply_driver_hacks(app, info, options)
# To be initialized with the Flask app object in app.py.
db = SQLiteAlchemy()
ma = Marshmallow()
At Engine Level
If you were using the declaritive implementation you would have access to the create engine function (and the scoped session one).
But assuming you're using the Flask-SQLAlchemy implementation, this just calls sqlalchemy.create_engine under the hood (on this line).
Might be a hack for the latter, as there doesn't seem to be a way to pass engine related options in; they are defined specifically a few lines up at #558:
options = {'convert_unicode': True}
At Session Level
This looks like it could be slightly easier, because you can pass session options when you initialise SQLAlchemy: see this line. The create_scoped_session method expects a dictionary which can be passed to the __init__ method as session_options.
So when you initialise the library you could try something like:
db = SQLiteAlchemy(session_options={'isolation_level': 'SNAPSHOT'})

H2 - The handle is invalid

not sure why this error occurs when running a select statement from my groovy console against an H2 instance in a different JVM (on the same host).
def sql = Sql.newInstance("jdbc:h2:~/mydb", "sa", "", "org.h2.Driver")
println sql.rows("select * from MESSAGES")
org.h2.jdbc.JdbcSQLException: IO Exception: "java.io.IOException: The handle is invalid"; "C:/Users/myhome/mydb.h2.db"; SQL statement:
select * from MESSAGES [90031-187]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:168)
at org.h2.message.DbException.convertIOException(DbException.java:330)
at org.h2.store.FileStore.seek(FileStore.java:297)
at org.h2.store.PageStore.readPage(PageStore.java:1324)
at org.h2.store.PageStore.getPage(PageStore.java:749)
at org.h2.index.PageDataIndex.getPage(PageDataIndex.java:233)
....
To access an H2 database from multiple VMs, it must run in server mode. The easiest way to do this is with AUTO_SERVER mode. Simply use this URL in both processes: jdbc:h2:~/mydb;AUTO_SERVER=TRUE
In AUTO_SERVER mode, H2 is smart enough to start up a server in the first VM and connect to it in the second, allowing transparent concurrent access to the same database.

MS SQL JDBC error on Execution exception - Invalid object name [Play 2.x scala app]

I'm using Play framework 2.x with SQL driver: com.microsoft.sqlserver.jdbc.SQLServerDriver
I'm trying to run a simple query:
SELECT [org].[name] FROM [ref].[organisations_bak] AS org
but I get the following error:
play.api.Application$$anon$1: Execution exception[[SQLServerException: Invalid object name 'ref.organisations_bak'.]]
at play.api.Application$class.handleError(Application.scala:293) ~[play_2.10-2.2.2.jar:2.2.2]
at play.api.DefaultApplication.handleError(Application.scala:399) [play_2.10-2.2.2.jar:2.2.2]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$12$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:165) [play_2.10-2.2.2.jar:2.2.2]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$12$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:162) [play_2.10-2.2.2.jar:2.2.2]
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33) [scala-library-2.10.3.jar:na]
at scala.util.Failure$$anonfun$recover$1.apply(Try.scala:185) [scala-library-2.10.3.jar:na]
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'ref.organisations_bak'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216) ~[sqljdbc4-4.0.2206.100.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515) ~[sqljdbc4-4.0.2206.100.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:792) ~[sqljdbc4-4.0.2206.100.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:689) ~[sqljdbc4-4.0.2206.100.jar:na]
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696) ~[sqljdbc4-4.0.2206.100.jar:na]
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715) ~[sqljdbc4-4.0.2206.100.jar:na]
I need to use the schema reference in my queries but I cant even get a simple query like this to work on my play app, simple queries without schema references work fine
SELECT name FROM organisations_bak
My Scala code looks like this:
import java.sql.ResultSet
import play.api.db.DB
DB.withConnection {
conn =>
val res = conn.createStatement.execute("SELECT [org].[name] FROM [ref].[organisations_bak] AS org")
}
Any help would be appreciated.
Thanks
In my case the issue was different user permissions. The server I used for development has been setup in some weird way that my user didn't have the permission to access the [ref] schema.
Just as a test I switched over to an AWS RDS SQL Server instance with the default DBA (owner) user settings and everything worked.
This means that the library and the code works it's my server that's at fault, but that's another issue.
try using
SELECT [org].[name] FROM [ref].[dbo].[organisations_bak] AS org

SQL Anywhere connection error: The driver doesn't support the version of ODBC behavior that the application requested

I'm trying to connect to a SQL Anywhere 5 database (I know it's olllld!) with a .NET 3.5 app in WinXP and it works fine from a stand alone console app. But when I run the exact code in a plugin ,running off a separate AppDomain, (the only difference I can tell between the two) with the following code, I get the errors further below.
BTW Both are executed as the SAME user.
using (OdbcConnection connection =
new OdbcConnection(strConnect))
{
OdbcCommand command = new OdbcCommand(query, connection);
command.CommandType = CommandType.Text;
DataTable posRecordsTable = new DataTable();
connection.Open();
OdbcException Exception returns the following errors:
Index #0
Message: [Sybase][ODBC Driver]Unable to connect to database server: database engine not running
Index #1
Message: [Sybase][ODBC Driver]Invalid connection string attribute
Index #2
Message: [Sybase][ODBC Driver]Invalid connection string attribute
Index #3
Message: [Microsoft][ODBC Driver Manager] The driver doesn't support the version of ODBC behavior that the application requested (see SQLSetEnvAttr).
Does the driver on your AppDomain have the same configuration as your stand alone box? I think checking the similarity of the environments will help you. Usually such errors are resolved by looking at the config files from where the driver reads its information. Dont know much about SQL Anywhere, but in general, I've come across such issues and I fixed them by altering the connection information or the configuration file.

How to connect an Oracle Database to Mathematica?

I am trying to connect an Oracle database to Mathematica 8. Another question already says how it can be done in for a MySQL database but it does not work for me:
Needs["DatabaseLink"] AND conn = OpenSQLConnection[JDBC["MySQL(Connector/J)",
"yourserver/yourdatabase"], "Username" -> "yourusername", "Password" -> "yourpassword"]
The following information is available for me on my desktop:
filepath = "C:\oracle\ora92\network\ADMIN\tnsnames.ora"; HOST; PORT; username; password;
conn = OpenSQLConnection[JDBC["MySQL(Connector/J)", HOST], "Username" -> username, "Password" -> password]
Error message: JDBC::error:
Communications link failure The last packet sent successfully to the server was 0 milliseconds ago.
The driver has not received any packets from the server. >>
Does anyone know how I can connect or continue?
Mathematica 8 does not come pre-equipped with an Oracle driver, a fact that can be verified by evaluating these expressions:
Needs["DatabaseLink`"]
JDBCDriverNames[]
(*
Out[2]= {Microsoft Access(ODBC),hsqldb,HSQL(Memory),HSQL(Server),
HSQL(Server+TLS),HSQL(Standalone),HSQL(Webserver),HSQL(Webserver+TLS),
jtds_sqlserver,jtds_sybase,mysql,MySQL(Connector/J),ODBC(DSN),odbc,
PostgreSQL,Microsoft SQL Server(jTDS),Sybase(jTDS),HSQL 2.0.1}
*)
We will have to follow the instructions in the Mathematica documentation that describes how to install a new JDBC driver.
First, we will have to create a new resource directory in which to place the necessary JDBC driver JAR file:
$jarDirectory =
CreateDirectory #
FileNameJoin #
{$UserBaseDirectory, "Applications", "Oracle", "Java"}
Next, we must select a JDBC driver to use. Visit the relevant Oracle page to find the correct JDBC driver for your database.
Chose a driver version that is compatible with Java 6, the version that Mathematica 8 uses internally. For this example, I chose to use the Oracle 11.2.0.2.0 driver for Java 6. Download the file and then move it into the resource directory just created:
SystemOpen[$jarDirectory]
Next, we will create a JDBC driver configuration file so that the new driver is registered with Mathematica:
$configDirectory =
CreateDirectory #
FileNameJoin #
{$UserBaseDirectory, "Applications", "Oracle", "DatabaseResources"}
Export[
FileNameJoin # {$configDirectory, "Oracle.m"}
, JDBCDriver[
"Name" -> "Oracle"
, "Driver" -> "oracle.jdbc.driver.OracleDriver"
, "Protocol" -> "jdbc:oracle:thin:#"
, "Version" -> 1
]
, "Text"
]
The driver is now installed:
JDBCDriverNames[]
(*
Out[9]= {Oracle,Microsoft Access(ODBC),hsqldb,HSQL(Memory),HSQL(Server),
HSQL(Server+TLS),HSQL(Standalone),HSQL(Webserver),HSQL(Webserver+TLS),
jtds_sqlserver,jtds_sybase,mysql,MySQL(Connector/J),ODBC(DSN),odbc,
PostgreSQL,Microsoft SQL Server(jTDS),Sybase(jTDS),HSQL 2.0.1}
*)
If the fates are smiling, we can now establish a connection and execute an SQL query:
$connection =
OpenSQLConnection[
JDBC["Oracle", "myserver:1521:mysid"]
, "Username" -> "scott"
, "Password" -> "tiger"
]
SQLExecute[$connection, "SELECT 'success!' FROM DUAL"]
... where myserver is the database server name, 1521 is the listener port number and mysid is the Oracle System ID (SID).
Oracle JDBC URLs come in many forms. For details, take a look at the Oracle FAQ.
I suspect that you are using the wrong JDBC driver - you should be using the Oracle JDBC driver, rather than MySQL one. When I was using DatabaseLink to connect to an Oracle database, I used this command:
OpenSQLConnection[
JDBC[
"oracle.jdbc.driver.OracleDriver",
"jdbc:oracle:thin:#server:port:dbname"
],
"Name" -> "dbname",
"Username" -> "YourUserName",
"Password" -> "YourPassword"
]
You should make sure to put the proper Oracle JDBC driver (corresponding to your Oracle db version) into a place where Mathematica can find it. This procedure is described in the documentation for the DatabaseLink, section JDBC Connections. You can test which JDBC drivers are visible to Mathematica by executing JDBCDrivers[]. Make sure that you install and use the correct driver corresponding to your DB version, b.t.w. - incorrect driver versions may result in very nasty and non-obvious bugs (this is unrelated to Mathematica).
My guess would be that you shouldn't use MySQL JBDC connections for Oracle. Although it is for Mathematica 5.2, here is an article that you perhaps can use as something to go from.
I've barely used Mathematica, and certainly not with a database, but from that page, it looks like you can do this:
OpenSQLConnection[JDBC["oracle","server.business.com:1999"],
Username -> "you"]
Whilst the answer from WReach above is correct it may also be helpful to know that there are 2 additional lines that are useful - namely to make sure Jlink is loaded and the Java ClassPath is correct and pointing to your oracle jdbc6.jar file.
Needs["JLink`"]
AddToClassPath[
FileNameJoin[{$UserBaseDirectory, "Applications", "Oracle",
"Java"}]];
or if using the answer verbatim just
Needs["JLink`"]
AddToClassPath[$jarDirectory];