From: Magnus <ma...@th...> - 2003-06-03 09:35:52
|
At 02:36 2003-06-03 -0500, Ian Bicking wrote: >If you want class X to act differently for two different databases, then >you either need something more than __sqlrepr__ (like __sqlrepr_pg__, >__sqlrepr_oracle__), or maybe __sqlrepr__ gets called with the driver >name, or you implement your own thing in the quote function. __sql_type__ or __sql_literal__ would need to be combined with a unified way of representing the date in question. Then it's up to the db driver that supports __sql_literal__ => DATE to be able to convert from a common format to the backend specific. I suggest that we simply catalog literal formats beyond the ones described in the SQL standard. Obviously BOOL is needed for instance. But remember: We don't need to keep track of every *TYPE*, only every kind of *LITERAL*. There are a whole bunch of numeric types for instance, but only two types of numeric literals, EXACT (e.g. -0.2) and APPROXIMATE (e.g. 31.4159E-1). If as a certain kind of literal is only useful for one particular driver/backend, we might as well use RAW, but as soon as more than one driver/backend supports a literal, we should have a standard way of describing that literal. I'm beginning to feel that maybe we should have a __sql_value__ rather than __sql_repr__ ... Something like in this example: class Bool(int): def __new__(cls, val): return int.__new__(cls, val and 1 or 0) def __sql_literal__(self): return db.literal.BOOL def __sql_value__(self): return self Then execute for PostgreSQL could do something like... ... elif value.__sql_literal__(self) == literal.BOOL: return ['FALSE', 'TRUE'][value.__sql_value__()] ... >For instance, lets say datetime defines its own __sqlrepr__ that outputs >a string with an ISO date as its contents. But now you, not the author >of datetime, finds out Access doesn't like that, so you override quote >and do a special check to fix up this specific case. In a case like that, you can always use RAW. This means that your class will have to give different results on calls to __sql_literal__ and __sql_repr__ on different backends, but that's doable, isn't it? I guess passing in the dbmodule or it's name might make in easier, but I think this should be an exceptional thing. For the exceptional cases you could build explicit SQL strings. I don't want it to become a norm that the applications contain a lot if backend specific conversion code. After all, that's what parameter passing should handle for us. What I want to provide is a method to inform the db interface how it should handle an object, when this object is not a type or class that it knows. A catalog could perhaps start like this: __sql_literal__ __sql_value__ RAW string, not to be quoted or escaped. CHAR string NCHAR unicode string NUMBER float, long or int BOOL 1 (True) or 0 (False) DATE mx.DateTime.DateTime (or the new datetime) TIMESTAMP mx.DateTime.DateTime TIME mx.DateTime.DateTimeDelta INTERVAL mx.DateTime.DateTimeDelta BIT string containing only [01] HEX string containg only [0-9A-Fa-f] NULL None BLOB binary string or stream object (StringIO, File...)? -- Magnus Lycka (It's really Lyckå), ma...@th... Thinkware AB, Sweden, www.thinkware.se I code Python ~ The Agile Programming Language |