On 10/18/2016 04:03 AM, Daniele Senigagliesi wrote:
Hi, I'm having some trouble with connection management in sqlalchemy.

In my environment I have an already created connection with psycopg2,
and some other components are still using it outside sqlalchemy.

I'd like create a new engine for sqlalchemy using the already created
connection; without modifing it; letting other components of the
environment working same as before.

At the moment I'm creating engine this way:

    create_engine( 'postgresql+psycopg2://', creator = _getConn,
    poolclass=NullPool )


_getConn is a function returning the connection from psycopg2, already
open.

My problem is that seam like this engine is modifing default enconding
of preexisting connection, and is changing default encoding of strings
returning from it. I just want sqlalchemy use that connection without
touching it, I also have connection pool managment at high level so I
don't strictly need sqlalchemy managment with it.

So I'd like sqlalchemy just use my connection, without even trying
reopeing it.

So for this approach, I'd recommend getting used to reading through the dialect source code, in this case it should be just the one file lib/sqlalchemy/dialects/postgresql/psycopg2.py. The SQLAlchemy dialect / engine considers the database connections to be "owned" by it, so it reserves the right to establish settings on the connection. Changes to this logic are pretty infrequent these days but that's no guarantee we may need to set some new psycopg2 setting in order to make something else work.

The other approach would be for you to create a wrapping object around the psycopg2 connection that proxies all methods, and just ensures the methods you don't want called have no effect. But even then you still probably need to stay aware of what might be called and what assumptions the dialect is making about the connection.

In this case we can see all the things done to the connection below. client_encoding in fact defaults to None, so there should be no call to set_client_encoding() emitted. Same for isolation_level. It's also registering unicode extensions based on use_native_unicode, that's True by default so you'd want to pass use_native_unicode=False to your create_engine().


    def on_connect(self):
        extras = self._psycopg2_extras()
        extensions = self._psycopg2_extensions()

        fns = []
        if self.client_encoding is not None:
            def on_connect(conn):
                conn.set_client_encoding(self.client_encoding)
            fns.append(on_connect)

        if self.isolation_level is not None:
            def on_connect(conn):
                self.set_isolation_level(conn, self.isolation_level)
            fns.append(on_connect)

        if self.dbapi and self.use_native_uuid:
            def on_connect(conn):
                extras.register_uuid(None, conn)
            fns.append(on_connect)

        if self.dbapi and self.use_native_unicode:
            def on_connect(conn):
                extensions.register_type(extensions.UNICODE, conn)
                extensions.register_type(extensions.UNICODEARRAY, conn)
            fns.append(on_connect)

        if self.dbapi and self.use_native_hstore:
            def on_connect(conn):
                hstore_oids = self._hstore_oids(conn)
                if hstore_oids is not None:
                    oid, array_oid = hstore_oids
                    kw = {'oid': oid}
                    if util.py2k:
                        kw['unicode'] = True
                    if self.psycopg2_version >= \
                            self.FEATURE_VERSION_MAP['array_oid']:
                        kw['array_oid'] = array_oid
                    extras.register_hstore(conn, **kw)
            fns.append(on_connect)

        if self.dbapi and self._json_deserializer:
            def on_connect(conn):
                if self._has_native_json:
                    extras.register_default_json(
                        conn, loads=self._json_deserializer)
                if self._has_native_jsonb:
                    extras.register_default_jsonb(
                        conn, loads=self._json_deserializer)
            fns.append(on_connect)

        if fns:
            def on_connect(conn):
                for fn in fns:
                    fn(conn)
            return on_connect
        else:
            return None









Would someone suggest me engine configuration or approach?

Thanks a lot

--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and
Verifiable Example. See http://stackoverflow.com/help/mcve for a full
description.
---
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
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to