I am using pyodbc to manage my database connections. I am attempting to connect to an OSI PI database and receive this error:
pyodbc.Error: ('IM002', "[IM002] [OSI][PI ODBC][PI]PI-API Error <pilg_getdefserverinfo> 0 (0) (SQLDriverConnectW); [01000] [Microsoft][ODBC Driver Manager] The driver doesn't support the version of ODBC behavior that the application requested (see SQLSetEnvAttr). (0)")
After talking with the vendor, I got this response:
Looks like pyodbc is written against ODBC 3.x. The OSI PI ODBC driver is using ODBC 2.0. The python ODBC driver manager will convert most ODBC 3 calls on the fly to ODBC 2 ones. Anything added to 3, however, will obviously fail. You would need to find some way to make sure that your only using 2.0 compliant ODBC calls. Currently their is not a PI ODBC driver that is compliant with ODBC 3.0.
My code is fairly simple as I'm just attempting to connect at this point:
import pyodbc
constr = 'DRIVER={PI-ODBC};SERVER=myserver;UID=MY_UID'
pyodbc.pooling=False
conn = pyodbc.connect(constr) # Error at this line
conn.close()
Has anyone connected python to OSI PI? If so, how did you do so? If not and you still used data in the OSI database, how did you end up accessing it?
I figured out how to do this. I had to change from using pyodbc though. Instead, I'm doing this with win32com.
Example
from win32com.client import Dispatch
oConn = Dispatch('ADODB.Connection')
oRS = Dispatch('ADODB.RecordSet')
oConn.ConnectionString = "Provider=PIOLEDB;Data Source=<server>;User ID=<username>;database=<database>;Password=<password>"
oConn.Open()
if oConn.State == 0:
print "We've connected to the database."
db_cmd = """SELECT tag FROM pipoint WHERE tag LIKE 'TAG0001%'"""
oRS.ActiveConnection = oConn
oRS.Open(db_cmd)
while not oRS.EOF:
#print oRS.Fields.Item("tag").Value # Ability to print by a field name
print oRS.Fields.Item(0).Value # Ability to print by a field location
oRS.MoveNext()
oRS.Close()
oRS = None
else:
print "Not connected"
if oConn.State == 0:
oConn.Close()
oConn = None
Notes:
This requires the PIOLEDB driver provided by OSISoft is installed on the machine that runs this code.
Performance doesn't seem horrible with this method. I was able to pull back several hundred thousand records with some of my other queries and it returned in an acceptable amount of time
Try to use this http://pypi.python.org/pypi/ceODBC/2.0.1
Related
im trying to make a connection to an as400 with db2 using pyodbc and the ibm db2 odbc driver.
import pyodbc
connection = pyodbc.connect(
driver='{IBM DB2 ODBC DRIVER}',
system='192.168.1.100',
uid='user',
pwd='pass')
c1 = connection.cursor()
#this is meaningless sql, i just want the connection
c1.execute('select * from libname.filename')
for row in c1:
print (row)
Running this gives me this error
python pydata.py
Traceback (most recent call last):
File "C:\Users\tca\Desktop\ScriptingSTuff\pydata.py", line 3, in <module>
connection = pyodbc.connect(
pyodbc.OperationalError: ('08001', '[08001] [IBM][CLI Driver] SQL1013N The database alias name or database name "" could not be found. SQLSTATE=42705\r\n (-1013) (SQLDriverConnect)')
Any ideas?
This is all under win10
EDIT:
Adding this "database='s10c38ft',"
import pyodbc
connection = pyodbc.connect(
driver='{IBM DB2 ODBC DRIVER}',
system='192.168.1.100,8471',
database='s10c38ft',
uid='user',
pwd='pass')
c1 = connection.cursor()
c1.execute('select * from libname.filename')
for row in c1:
print (row)
Makes it hang on a blinking cursor, I cant even CTRL+C to end it, I have to close cmd.
The proper driver name should be IBM i Access ODBC Driver (but see notes below). Other than that, your first example was correct:
connection = pyodbc.connect(
driver='{IBM i Access ODBC Driver}',
system='192.168.1.100',
uid='user',
pwd='pass')
If that doesn't work, there are two main possibilities:
You are using an old ODBC driver. This would happen if you are using the old iSeries Access (in which case the driver name is iSeries Access ODBC Driver) or even older Client Access (driver name Client Access ODBC Driver (32-bit)). If you choose the appropriate name for your driver, it will work.
You are using an ODBC driver that is not for IBM i. The most commonly used member of the Db2 family is Db2 for LUW (Linux, Unix, Windows), but there are others. None of these will work for you.
You can find out the list of exact ODBC driver names you have installed by calling pyodbc.drivers(). If you don't have any of the ones I mentioned above by name, then you don't have the right driver. The ODBC driver you want is the one described here.
I'm using SQL Server with SQLAlchemy 1.3.18 library and thanks to fast_executemany = True, it's now faster than before.
I have to make the link with a Sybase Database. I've got the following error:
TypeError : Invalid argument(s) 'fast_executemany' sent to create_engine(),using configuration SybaseDialect_pyodbc/QueuePool/Engine.
This is going to be a problem for me because I want a quick connection and also quick writing on my db.But even if I erase these arguments from the method, I've got the following error :
sqlalchemy.exc.OperationnalError : (pyodbc.OperationnalError)
here is the code:
engine = sqlalchemy.create_engine(con['sql']['connexion_string'])
with con['sql']['connexion_string'] = "sybase+pyodbc://<user>:<password>#server_name/[db_name]driver=ODBC Driver 13 for SQL Server"
I think it comes from the driver (maybe I'm wrong), but I don't know which one take, and in the documentation, I've understood we have to use pyodbc so ODBC Drivers.
The internal sybase dialect does not support fast_executemany, but the external dialect does.
Note that you will need to use SAP's ODBC driver for ASE; FreeTDS ODBC won't work with fast_executemany.
So after many search, i've found something where it's workin for me.
yo have to writre like an odbc connexion:
params = (
"DRIVER = "+driver+";"\
"SERVER = "+server+";"\
"DATABASE = "+database+";"\
"PORT = "+port+";"\
"UID = "+user+";"\
"PWD= "+password+";"
params = urllib.parse.quote_plus(params)
where params is your odbc connexion.
And then do this :
connexion_string = 'sybase+pyodbc:///?odbc_connect = %s'%params)
with this connexion string, you're able to do sqlalchemy.create_engine(connexion_string)
For those in the future, this is how i fixed my problem on Windows:
get ODBC dsn path: start>control_panel>admin_tools>ODBC_Data_source(64-bit)>
2 options here: check the system DSN tab. you might see something named like 'prototype' with SQL Anywhere 17 Driver.
or youll have to create your own DSN under File Dsn > Add > {select your dialect} > {Browse to save file path} > then click Finish. youll be prompted to fill in your Sql Anywhere info.... database name, Uid, PWD, etc...
check out Chad Kenneedy's answer to setup custom ODBC Pyodbc error Data source name not found and no default driver specified paradox
make sure to test Dsn connection when you got it all figured out.
once thats done,
engine = create_engine("sybase+pyodbc://<DSN_username>:<DSN_password>#<DSN_file_name,eg_prototype>")
I am trying to connect to a Sybase ASE 15 database on windows using sqlalchemy (1.0.9) and pyodbc. If I use a DNS url everything works as expected:
url = r'sybase+pyodbc://usename:password#dns'
engine = create_engine(url, echo=True)
Session = sessionmaker(bind=engine)
sess = Session()
conn = sess.connection()
However, if I avoid the DNS I get an error message:
url = 'sybase+pyodbc://username:password#host:port/database?driver=Adaptive Server Enterprise'
, I get an error:
DBAPIError: (pyodbc.Error) ('01S00', '[01S00] [SAP][ASE ODBC
Driver]Invalid port number (30011) (SQLDriverConnect)')
The port number is correct and it is the same port as specified in the DNS.
Any ideas?
It may be worth trying to work with some version of the semicolon-separated DSN-less format used by pyODBC (and ODBC in general). Some examples here:
http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/
This question tackles a similar issue with FreeTDS, but the concept is the same, as the connect string is basically passed through to the low-level ODBC connect:
SqlAlchemy equivalent of pyodbc connect string using FreeTDS
The URL is being parsed down to this type of string for ultimate connection by pyodbc through to SQLDriverConnect (in the ODBC API), so specifying the ASE ODBC DSN-less connection string directly may work better.
Update: Ran a quick test to see what connect arguments are produced for this URL:
from sqlalchemy.engine.url import *
from sqlalchemy.connectors.pyodbc import *
connector = PyODBCConnector()
url = make_url("sybase+pyodbc://username:password#host:5555/database?driver=Adaptive Server Enterprise")
print connector.create_connect_args(url)
This results in:
[['DRIVER={Adaptive Server Enterprise};Server=host,5555;Database=database;UID=username;PWD=password'], {}]
Note that the hostname and port are separated by a comma, per http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/tds-based-odbc-driver-from-sybase-ocs-125/, this format works for TDS-based ODBC for Sybase 12.5:
Driver={Sybase ASE ODBC Driver};NetworkAddress=myServerAddress,5000;
Db=myDataBase;Uid=myUsername;Pwd=myPassword;
However, the ASE 15 format (http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/adaptive-server-enterprise-150/) specifies server=myServerAddress;port=myPortnumber with port as a key passed in the semicolon-delimited string:
Driver={Adaptive Server Enterprise};app=myAppName;server=myServerAddress;
port=myPortnumber;db=myDataBase;uid=myUsername;pwd=myPassword;
If you "cheat" on the port spec by using host;port=5555, you get:
[['DRIVER={Adaptive Server Enterprise};Server=host;port=5555;Database=database;UID=username;PWD=password'], {}]
But this just feels like a Bad Idea™, even if it works. I'd also note that the generated string is using Database as the key vs. Db in the Sybase connection string reference. This may prove to be an issue as well.
Using ?odbc_connect as in the linked question is probably your best option for controlling the exact connect arguments being sent to ODBC.
I have recently installed Microsoft SQL Server 2014 on my PC as I want to create a database for a web application I am building (I have been learning Python for a year and have very basic experience with SQLite).
After installing SQL Server 2014 and creating a database called Users, I am just trying to run some very basic commands to my database but I am falling at the first hurdle over and over!
I have installed pymssql and pyodbc and tried running commands directly with these but have failed. (e.g. pymssql gives me a TypeError: argument of type 'NoneType' is not iterable when I set the variable conn = pymssql.connect(server, user, password, "tempdb")
My latest attempt is to use SQLalchemy to achieve my long awaited connection with SQL database. However, after installing this, it is failing on the following error:
"sqlalchemy.exc.OperationalError: (pymssql.OperationalError) (20009, 'DB-Lib error message 20009, severity 9:\nUnable to connect: Adaptive Server is unavailable or does not exist\nNet-Lib error during Unknown error (10035)\n')"
The question I need answering is, how do I start talking to my database using SQLalchemy?
The code I am using is as follows:
from sqlalchemy import *
engine = create_engine('mssql+pymssql://Han & Lew:#SlugarPlum:1433/Users')
m = MetaData()
t = Table('t', m,
Column('id', Integer, primary_key=True),
Column('x', Integer))
m.create_all(engine)
Yes, my PC is called SlugarPlum. User is Han & Lew. And my server is called THELROYSERVER. DSN = 1433. No password. (I don't know if it is wise that I am giving this information online but the data I have is not sensitive so I guess it's worth a shot.)
Also, if anyone can direct me to an ultra-beginners resource for Python-SQL server that would be awesome as I am getting beaten up by how complex this seems to be!
Here's a connect function and example for connecting via pyodbc. Connecting via pymssql should be as easy as formatting the connecting string for pymssql. I've provided Windows and Linux options, but only tested on Linux. I hope it helps.
def sqlalchemy_connect(connect_string):
""" Connect to the database via ODBC, start SQL Alchemy engine. """
def connect():
return pyodbc.connect(connect_string, autocommit=True)
db = create_engine('mssql://', creator=connect)
db.echo = False
return db
def main():
global DBCONN
# Linux with FreeTDS
connect_string = "DRIVER={FreeTDS};SERVER=<server name>;PORT=<port num>;DATABASE=<db>;UID=<user>;PWD=<password>;TDS_Version=<version num>;"
# Windows with SQL Server
connect_string = "DRIVER={SQL Server};SERVER=<server name>;PORT=<port num>;DATABASE=<db>;UID=<user>;PWD=<password>;"
DBCONN = sqlalchemy_connect(connect_string)
if __name__ == "__main__":
main()
I downloaded Python 2.7 (python-2.7.1.amd64.msi) and pyodbc, the python extension module for connecting to DB2 database (i.e. pyodbc-2.1.8.win-amd64-py2.7.exe).
I wrote sample script as shown below.
import csv
import pyodbc
conn = pyodbc.connectpyodbc.connect('DRIVER={DB2};SERVER=localhost;DATABASE=DBT1;UID=scott;PWD=tiger;')
curs = conn.cursor()
curs.execute('select count(edokimp_id) from edokimp')
print curs.fetchall()
The script throws following error
pyodbc.Error: ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnectW)')
As I am a newbie to Python, I realized from the error that I need to download the IBM DB2 driver for pyodbc and hence searched extensively on Google but couldn't find any.
I would greatly appreciate if you could point me to the site where I can download the driver and later explain me how to configure/load the driver.
In case of Java
the driver will be shipped in the form of ojdbc.jar which will be copied to the lib directory which will be on classpath
make changes to configuration file
reference the DataSource from Java Class
I am newbie to Python so I would greatly appreciate if you could let me know cooresponding steps with an example in Python.
You can get the PyDB2 driver on the project homepage.
If you run into compilation issues with the official Python, ActivePython is a good alternate distribution of Python on Windows.
Edit: If it asks you for DB2 headers, you need to get the IBM Data Server Client for ODBC and CLI.
It does work using pyodbc. I think you have a wrong connection string. After some research and tests I solved with this code:
con = pyodbc.connect('DRIVER=iSeries Access ODBC Driver;SYSTEM=10.0.0.1;UID=bubi;PWD=xyz;DBQ=DEFAULTSCHEMA;EXTCOLINFO=1')
cur = con.cursor()
cur.execute('select * from MYTABLE')
row = cur.fetchone()
if row:
field1 = row[0]
field2 = row[1]
# etc...
As you see it doesn't need a DSN to be configured on your system.
This connection string for pyodbc, work for me:
conexion_str = 'SYSTEM=%s;db2:DSN=%s;UID=%s;PWD=%s;DRIVER=%s;' % (self._SYSTEM, self._DSN, self._UID, self._PWD, self._DRIVER)
self._cnn = pyodbc.connect(conexion_str)