![]() |
|
|
|
Python and ActiveX Data Objects (ADO)
This is the 'sister' page to
Bill Wilkinson's
page on using Python with Microsoft's Data Access Objects (DAO).
It is intended to give the basics on using Python
to connect to an MS Access 2000 database via
Microsoft's ActiveX Data Objects (ADO). There are several reasons you might want to do this.
ADO is lighter and it tends to be a bit and faster than DAO,
unlike DAO it can easily be used with other databases (SQL Server, Oracle, MySQL, etc.),
it can be used with XML and text files and pretty much any data at all,
and Microsoft will be supporting it for a longer time than DAO. Table of Contents
>>> import win32com.client
>>> conn = win32com.client.Dispatch(r'ADODB.Connection')
>>> DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:/MyDB.mdb;'
>>> conn.Open(DSN)
With these set up access to the database is fairly straight forward.
>>> rs = win32com.client.Dispatch(r'ADODB.Recordset')
>>> rs_name = 'MyRecordset'
>>> rs.Open('[' + rs_name + ']', conn, 1, 3)
[The 1 and the 3
are constants for adOpenKeyset and adLockOptimistic
and are well beyond the scope of this tutorial.
I typically use these settings as defaults, but your mileage may vary. Pick up a book on ADO for details.]
>>> flds_dict = {}
>>> for x in range(rs.Fields.Count):
... flds_dict[x] = rs.Fields.Item(x).Name
A field's type and size are returned by ...
>>> print rs.Fields.Item(1).Type
202 # 202 is a text field
>>> print rs.Fields.Item(1).DefinedSize
50 # 50 Characters
>>> rs.AddNew()
>>> rs.Fields.Item(1).Value = 'data'
>>> rs.Update()
These values can be also be returned.
>>> x = rs.Fields.Item(1).Value
>>> print x
'data'
So, if one wants to create a new Record, and know what number an AutoNumber field has generated for it without
having to query the database ...
>>> rs.AddNew()
>>> x = rs.Fields.Item('Auto_Number_Field_Name').Value
# x contains the AutoNumber
>>> rs.Fields.Item('Field_Name').Value = 'data'
>>> rs.Update()
>>> oCat = win32com.client.Dispatch(r'ADOX.Catalog')
>>> oCat.ActiveConnection = conn
>>> oTab = oCat.Tables
>>> for x in oTab:
... if x.Type == 'TABLE':
... print x.Name
>>> conn.Close()
>>> conn = win32com.client.Dispatch(r'ADODB.Connection')
>>> DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:/MyDB.mdb;'
>>> sql_statement = "INSERT INTO [Table_Name]
([Field_1], [Field_2]) VALUES ('data1', 'data2')"
>>> conn.Open(DSN)
>>> conn.Execute(sql_statement)
>>> conn.Close()
>>> # See example 3 above for the set-up to this
>>> rs.MoveFirst()
>>> count = 0
>>> while 1:
... if rs.EOF:
... break
... else:
... count = count + 1
... rs.MoveNext()
Aside from being horribly inefficient, if the recordset is empty, moving to the first record will generate an error.
ADO provides a way to correct this. Before opening the recordset, set the CursorLocation to 3.
After opening the recordset, the recordcount will be available.
>>> rs.Cursorlocation = 3 # don't use parenthesis here
>>> rs.Open('SELECT * FROM [Table_Name]', conn) # be sure conn is open
>>> rs.RecordCount # no parenthesis here either
186
[Again, the 3
is a constant.]
This really just scratches the surface of ADO, but it should help getting connected from Python.
For anything more than just simple database scripting it is worth looking into the object model.
Here are some links that might be helpful.http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmscadoobjmod.asp http://www.activeserverpages.ru/ADO/dadidx01_1.htm Please contact me with questions or comments. I have placed a number of old questions and replies online. Feel free to contact me with questions, but I may use your question publicly. I will, of course, remove any identifying information. |