On 6/25/14, 2:53 PM, Jason Newton wrote:
> Seems to fly in the face at the point of SQLA although integration
> difficulties are appreciated.  Most advanced postgresql drivers in any
> language bindings have added support for this type although none of
> them can hide that it's file like. 
SQLA doesn't go out of its way for unusual, very database-specific
features that up til now have demonstrated little to no real-world use
(nobody's ever asked for this feature before and googling about
Postgresql LOBs turns up very little).  There are tons of examples of
features like this across many different database backends.  If they are
easy to add, we add them, or if they are easy to address via a recipe,
we add the recipe up to the wiki.

But if the behavior requires substantial changes to the core and
dialect, and the ratio of complexity of impact to sparseness of need is
really high, it's not worth it and actually kind of damaging to most
users to complicate the library for use cases that are extremely rare
and can just as well be addressed by dropping down to raw DBAPI code. 
Complications/destabiliziations/performance degradations that are
hoisted onto the whole userbase for the benefit of a single feature that
is virtually never needed is the wrong choice to make; I'm presented
with this choice all the time and there's nearly always work to be done
in extricating ill-conceived features and behaviors that went in too
quickly.  I'm pretty confident that this feature won't require any of
that, but that remains to be seen.

Just in case this wasn't apparent, you certainly *can* use psycopg2's
bindings when you're in an otherwise SQLAlchemy app.  Worst case you can
retrieve a raw psycopg2 connection using connection.raw_connection and
do whatever you need.  If you truly have some use for LOBs, SQLAlchemy
isn't preventing you from using it, it's just not providing any niceties
around it.   The fact that these unusual use cases are not ever
prohibited by SQLA further raises the bar to adding first class support
for them.


> PG's BYTEA is NOT arbitrarily large, it has quite real practical
> limits and I've hit them regularly in storing compressed HDF5
> documents in the database as part of a bench testing framework.  The
> theoretical limit is 1GB but this limit is far less in practice
> (http://www.postgresql.org/message-id/cafj8pracfkoinp2uxeizod5krx29n2ofsoldh0w6ej7rxko...@mail.gmail.com
> ) . http://www.postgresql.org/docs/9.3/static/storage-toast.html  I'm
> not looking for streaming, retrieve/set binary buffers.  It'd be nice
> to translate it transparently to HDF5 python in-memory objects (ie h5py).
Python translation is very easy in SQLA, its just if you have special
needs for SQL syntaxes, that's where special behaviors may be needed. 
So far it sounds like the only blocking factor is that bind_sql needs to
distinguish between INSERT and UPDATE.  that's not a terribly tall order
though it is inconvenient in that the API would need a
backwards-compatibility layer.


>  
>
>
>     As the feature involves SQL functions I don't think you'd be
>     dealing only with bind_processor(), the SQL functions themselves
>     would probably be via SQL-level processing, see
>     
> http://docs.sqlalchemy.org/en/rel_0_9/core/types.html#applying-sql-level-bind-result-processing.
>    
>     It's true these functions aren't given access to the compiler
>     context where you'd be able to discern INSERT from UPDATE, so I'd
>     probably use two variants of datatype, an InsertLOB and UpdateLOB
>     datatype, then I'd apply these to an INSERT or UPDATE statement at
>     runtime probably using a @compiles decorator -
>     http://docs.sqlalchemy.org/en/rel_0_9/core/compiler.html, that is,
>     take the existing LOB type and just swap it out for
>     InsertLOB/UpdateLOB.    Adding compiler context to TypeEngine is
>     something we could look into as a feature as well so that
>     bind_expression() has this available somehow and switching around
>     types wouldn't be needed.
>
>
> Separate datatypes is clearly not a good approach to this.

Let me clarify that these separate datatypes would be totally invisible
to the user.   The user would work with a single LOB type.  Translation
to Insert/Update versions would not be explicit and would occur at the
point at which the insert/update construct is compiled.   At the moment
this may be the best approach short of modifying the library (but then
again I can't say much about the approach because i have little idea
what the SQL we're talking about looks like).
 
> Everything starts with a transaction block. 
the psycopg2 DBAPI is implicitly in a transaction block at all times
unless "autocommit" mode is set up, so there shouldn't be any problem here.

> Hand crafted inserts use server side lo_create(-1) (in sql) which
> allocates a new large object and returning clause to get the oid in
> one go back to the client side.  Then I start using the lobject api on
> the returned oid. 
I'd like to see explicit SQL, preferably in the form of a psycopg2
script that illustrates all the operations you wish to support and
specifically how they must interact with the database.


> In patches I've made to cppdb, in the bind of std::istream I call
> client side lo_create, lo_open, a sequence of lo_writes, and finally
> lo_close.  In retrospect this doesn't handle updates particularly well
> and maybe this could be used in sqlalchemy as is too - an update just
> allocates a new large object and unreferences the old one. 
I wonder why the mechanics of these functions can't be more cleanly
wrapped into server-side stored procedures?    If they can be distilled
into simple insert_lob() update_lob() functions that would potentially
be a better separation of duties.


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to