[PYTHON DB-SIG] TEXT and IMAGE datatypes in sybase ct module

Greg Stein gstein@microsoft.com
Wed, 16 Apr 1997 03:43:27 -0700


Oracle has a similar problem: you must bind the column appropriately.
This means that you must know before binding whether you'll bind as a
regular string (against, say, a VARCHAR column) or as a LONG (RAW)
column. Oracle does allow you, however, to bind the LONG value directly
for an insert/update.

Note: the existing modules return LONG columns (and their equivalents)
in dbiRaw instances. resultcolumn.value contains a Python string with
the actual data.

Handling of large blobs has been the trickiest part of any of the DBAPI
modules. Given the unique constraints of Sybase (this hasn't been seen
so far), then I think your solution sounds "best." In other words, move
the problem back to the application.

The DBAPI isn't meant to make clients of it truly portable across all
databases. That simply can't be done. There are too many differences in
SQL text, bindings, capabilities, restrictions, etc. Instead, it is
meant to provide a uniform method of interaction across the databases to
as great an extent as possible. An application that requires more
portability can code that at the Python level given their data handling
requirements and the set of target databases. This policy is close to
that of Python's policy towards C APIs: expose it and do no more. We
actually do more, but we can't do it all. Long and short: I think you
should be fine with your suggested approach.

Regarding the options: simply make them attributes of the connection or
cursor (whichever is appropriate), rather than dealing with an option
dictionary. Again, a client will know it is dealing with the Sybase
module and that those attributes will be present.

Whatever options that you *do* add, though, it would be nice to reflect
those in the DBAPI spec itself. We can label them all as Sybase
specific, but other module maintainers might see a handy parallel with
their modules and we could move some of the attributes towards
commonality. Having them doc'd, whether specific or not, will be a great
boon.

-g

	-----Original Message-----
	From:	Peter Godman [SMTP:pgodman@vgi.com]
	Sent:	Tuesday, April 15, 1997 11:11 PM
	To:	db-sig@python.org
	Subject:	[PYTHON DB-SIG] TEXT and IMAGE datatypes in
sybase ct module

	Hi Folks.  

	For some time I've been working on a DBAPI-compliant module for
Sybase
	ct-library.  ct-library is the more modern of Sybase's API's
(the other
	being db-library).  ct-library has the very nice feature that
Sybase
	provides an unsupported linux version of the library free of
charge, hence
	I can work on it in my free time. 

	I have a question regarding my treatment of TEXT and IMAGE types
in the
	module (equivalent, I believe, to Oracle LONG and LONG RAW
columns).  As I
	understand the specification, fetching these datatypes should
return
	Python strings, whereas supplying them as a parameter should be
done using
	dbi wrappers or just a string for TEXT.  This is fine.  However,
Sybase
	has a special interface for getting data into and out of long
columns.  In
	essence, if one wishes to insert a long value into a long
column, one must
	first fetch the CS_IODESC structure (similar to a file
descriptor) using a
	SELECT statement, and then send data down this channel to fill
in the long
	column.

	Imagining, then, that a user wishes to add a row to the
database, and
	supplies an input variable corresponding to a TEXT column.  In
order to
	fulfill this request, the sybase module would have to add the
row, somehow
	figure out how to fetch the row again (which can't be done if
there's no
	primary key (there are no row ids in Sybase)), obtain the
CS_IODESC, and
	send the contents of the variable. I believe such an interface
would be
	very difficult to implement (Updates are similarly difficult),
and be
	unclean. This leaves me with two alternatives.  I can either
provide an
	optional file-like interface to CS_IODESCs, so that fetching a
row with a
	TEXT or IMAGE can return a file-like object suitable for reading
and
	writing, or I can stipulate that users specify the contents of
long
	columns in-line in the SQL (which limits long contents to 100K
(maximum
	query length)).  I would prefer the former.  From what I know of
	Postgres, it seems it may be appropriate there also.

	For the file solution I'm imagining something like

	>>> cursor.execute('SELECT phone, description FROM phones')
	>>> result = cursor.fetchone()
	>>> print result
	['5551212', <iodesc for read/write at 8108ca8>]
	>>> print result[1].read()
	This is the description
	>>> result[1].write('information')

	Does anyone have any thoughts on this?  Do the other databases'
APIs not
	have this limitation?

	While I'm asking questions, I should also mention that in
Sybase, there
	are lots of behaviours one may configure on a per-connection
basis.  For
	example, one may specify whether COMMIT/ROLLBACK closes open
cursors, and 
	specify which ANSI isolation level the connection is operating
in. I'd
	like to include support for these options, but from the spec
don't see a
	portable way of doing it.  Anyone have any suggestions about
this?  I
	could imagine something like

	>>> import ctsybase
	>>> connection = ctsybase.ctsybase()
	>>> connection.options['CLOSE_CURSOR_ON_XACT'] = 1
	>>> connection.options['ISOLATION_LEVEL'] = 3
	>>> connection.options['FOO'] = 1
	SybaseError:  'FOO' is not a valid option for connection
	>>> print connection.options.keys()
	['CLOSE_CURSOR_ON_XACT', 'MAX_COMMANDS', 'MAX_TEXTLEN',
'ISOLATION_LEVEL']


	Thanks in advance for any ideas, suggestions, etc.

	Peter Godman
	pjg@vgi.com


	_______________
	DB-SIG  - SIG on Tabular Databases in Python

	send messages to: db-sig@python.org
	administrivia to: db-sig-request@python.org
	_______________

_______________
DB-SIG  - SIG on Tabular Databases in Python

send messages to: db-sig@python.org
administrivia to: db-sig-request@python.org
_______________