Am Dienstag, 1. Oktober 2013 17:19:11 UTC+2 schrieb Michael Bayer:

> here's a full proof-of-concept.   see if it works for you and if you can 
> figure out where your real app is diverging from the basic idea:
>
> from sqlalchemy import MetaData, Table, Column, String, Integer, 
> create_engine
>
> e = create_engine("sqlite://", echo=True)
>
> m1 = MetaData()
> t1 = Table('t1', m1, Column('data', String(50)))
> t1.create(e)
> e.execute(t1.insert(), data='d1')
>
> import sqlalchemy.types as types
> from sqlalchemy.schema import Table
> from sqlalchemy import event
>
> class MyStringType(types.TypeDecorator):
>     impl = types.String
>
>     def process_bind_param(self, value, dialect):
>         if value is not None:
>             value = value.encode('utf-8', 'replace')
>         return value
>
> @event.listens_for(Table, 'column_reflect')
> def listen_for_reflect(inspector, table, column_info):
>     if isinstance(column_info['type'], types.String):
>         column_info['type'] = MyStringType(column_info['type'].length)
>
> m2 = MetaData()
> t2 = Table('t1', m2, autoload=True, autoload_with=e)
>
> e.execute(t2.select().where(t2.c.data == u'd1')).fetchall()
>
>
>
>
> On Oct 1, 2013, at 4:12 AM, Tobias Bell <tobia...@gmail.com <javascript:>> 
> wrote:
>
>
>
> Am Montag, 30. September 2013 19:18:01 UTC+2 schrieb Michael Bayer:
>>
>>
>> On Sep 30, 2013, at 9:30 AM, Tobias Bell <tobia...@gmail.com> wrote:
>>
>> Hello
>>
>> I'm currently migrating a rather old application built with SQLAlchemy 
>> 0.6 and also an older cx_oracle to use SQLAlchemy 0.8 and cx_oracle 5.1.2.
>> The problem is, all queries with strings send unicode data to cx_oracle 
>> an cx_oracle uses NVARCHAR2 to talk to the database. The table itself has 
>> VARCHAR2 columns
>> and no SYS_OP_C2C() indexes. So full table scans are the result. What can 
>> I do to enforce that cx_oracle doesn't bind with NVARCHAR2?
>> What I tried till now was
>>
>>    - Forcing unicode conversion on engine leve - 
>>    sa.create_engine(connect_url, convert_unicode=True)
>>    - encoding parameter = param = param.encode('utf8')
>>
>> I found 
>> this<https://groups.google.com/forum/#!msg/sqlalchemy/8Xn31vBfGKU/bAGLNKapvSMJ>
>>  post, 
>> but couldn't use it because all my table definitions are autoloaded.
>> What would you suggest?
>>
>>
>> I've just gone through that thread for review, seems like nothing is 
>> really going to change with cx_oracle.  It would be great if they could 
>> send a bytestring through on their end, as any application in Python 3 that 
>> naively uses cx_oracle directly with VARCHAR columns is going to perform 
>> terribly otherwise.    The issue here is essentially using SQLAlchemy to 
>> fix a problem that cx_oracle isn't.
>>
>> Anyway, the same recommendations about custom types and/or 
>> convert_unicode='force' still apply here.  For reflection, use the column 
>> reflect event to upgrade types on each column as it is reflected.  
>>
>>
>> http://docs.sqlalchemy.org/en/rel_0_8/core/events.html?highlight=column_reflect#sqlalchemy.events.DDLEvents.column_reflect
>>
>> from sqlalchemy.schema import Table
>> from sqlalchemy import event
>>
>> @event.listens_for(Table, 'column_reflect')
>> def listen_for_reflect(inspector, table, column_info):
>>    if isinstance(column_info['type'], String):
>>        column_info['type'] = MyStringType(column_info['type'].length)
>>
>>
>> Thanks for the quick answer Michael. I just tried it now
>
> import sqlalchemy.types as types
> from sqlalchemy.schema import Table
> from sqlalchemy import event
>
> class MyStringType(types.TypeDecorator): 
>     impl = types.String
>
>     def process_bind_param(self, value, dialect): 
>         if value is not None: 
>             value = value.encode('utf-8', 'replace')
>
> event.listens_for(Table, 'column_reflect')
> def listen_for_reflect(inspector, table, column_info):
>    if isinstance(column_info['type'], types.String):
>        column_info['type'] = MyStringType(column_info['type'].length) 
>
> But it is not working. Is there something wrong with my code? Do you need 
> to see some more code? Here is an example query
>
> 2013-10-01 10:04:22,171 INFO:SELECT "POSTEINGANG_ADM".pe_process.status AS 
> "POSTEINGANG_ADM_pe_proce_1", "POSTEINGANG_ADM".pe_process.stack_id AS 
> "POSTEINGANG_ADM_pe_proce_2", "POSTEINGANG_ADM".pe_process.process_id AS 
> "POSTEINGANG_ADM_pe_proce_3", "POSTEINGANG_ADM".pe_process.rout_client AS 
> "POSTEINGANG_ADM_pe_proce_4", "POSTEINGANG_ADM".pe_process.rout_category AS 
> "POSTEINGANG_ADM_pe_proce_5", "POSTEINGANG_ADM".pe_process.rout_message AS 
> "POSTEINGANG_ADM_pe_proce_6", "POSTEINGANG_ADM".pe_process.archive_path AS 
> "POSTEINGANG_ADM_pe_proce_7", "POSTEINGANG_ADM".pe_process.fndoc_id AS 
> "POSTEINGANG_ADM_pe_proce_8", "POSTEINGANG_ADM".pe_process.fndoc_class AS 
> "POSTEINGANG_ADM_pe_proce_9", "POSTEINGANG_ADM".pe_process.fndoc_date AS 
> "POSTEINGANG_ADM_pe_proce_a", "POSTEINGANG_ADM".pe_process.scart AS 
> "POSTEINGANG_ADM_pe_proce_b", "POSTEINGANG_ADM".pe_process.host_stack_id AS 
> "POSTEINGANG_ADM_pe_proce_c", "POSTEINGANG_ADM".pe_process.altered_by AS 
> "POSTEINGANG_ADM_pe_proce_d", "POSTEINGANG_ADM".pe_process.retry_at AS 
> "POSTEINGANG_ADM_pe_proce_e", "POSTEINGANG_ADM".pe_process.discard_at AS 
> "POSTEINGANG_ADM_pe_proce_f", 
> "POSTEINGANG_ADM".pe_process.rout_specification AS 
> "POSTEINGANG_ADM_pe_proce_10" 
> FROM "POSTEINGANG_ADM".pe_process 
> WHERE :param_1 = "POSTEINGANG_ADM".pe_process.stack_id
> 2013-10-01 10:04:22,171 INFO:{'param_1': u'skcla0005982302000'}
>
> -- 
> 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+...@googlegroups.com <javascript:>.
> To post to this group, send email to sqlal...@googlegroups.com<javascript:>
> .
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
> Thank you very much! The problem was the missing return in 
process_bind_param(). It works now like a charm.

-- 
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/groups/opt_out.

Reply via email to