rsim / oracle-enhanced

Oracle enhaced adapter for ActiveRecord
MIT License
549 stars 310 forks source link

#write_lobs should always serialize attributes #2200

Closed akostadinov closed 2 years ago

akostadinov commented 3 years ago

#write_lobs only serializes attribute before writing to the database when it is ActiveRecord::Type::Serialized. Then value.to_s is written to the database ignoring ActiveRecord type serialization method.

Attributes should always be serialized before writing to the database. I don't see how custom attributes are supposed to be used otherwise.

A workaround for this would be to define #to_s of the custom attribute which does the same as serialization to database, but this is not often undesirable.

I tested with 1.7 as stated at the bottom but I see same logic used in master too.

Steps to reproduce

  1. have a CLOB column type
  2. have a field with custom attribute, e.g. class MyCustomAttribute < ActiveRecord::Type::Text
  3. try to use attribute
    my_model.myattribute = "whatever long serialized string ..."
    my_model.save!
    my_model.myattribute
    => whatever deserialized object as expected
    my_model.reload
    my_model.myattribute

Expected behavior

=> whatever deserialized object as expected

Basically everything works as if ActiveRecord::Type::Text has been used.

Actual behavior

=> "#<MyDeserializedClass:0x0000000010967bd8>tring ..."

System configuration

Rails version: 5.0.7.2

Oracle enhanced adapter version: activerecord-oracle_enhanced-adapter (1.7.11)

Ruby version: ruby 2.5.9p229bu

Oracle Database version: oracle:19.3.0

harsh288 commented 3 years ago

Hi @akostadinov I'm using fluentd and oracle enhanced plugin, and I have NCLOB & CLOB type of column, the data pushed from fluentd to Oracle for this column is always blank, in fact, it doesn't work of NCLOB, it complains empty NCLOB, do we need some settings for these types datatypes in order to work ??

Oracle : 18c version

akostadinov commented 3 years ago

@harsh288 , I think this is a different issue. Does your backtrace point back at #write_lobs? #write_lobs is run after regular UPDATE query in case value is not null. My expectation is that you see the issue during the regular UPDATE query.

In my project we quote CLOB data in to_clob() as far as I understood exactly to handle blank values. Maybe a similar function for NCLOB also exists. In either case it is a separate issue so you may file one.

harsh288 commented 3 years ago

Sorry @akostadinov, I know you are looking for some solution and I 'm here asking for a help, I 'm not sure how to resolve this issue in fluentd, below is the configuration that I have done.

<match MIOLogMessage>
    @type sql
    flush_interval 10
    host localhost
    database GOAORA
    port 1521
    adapter oracle_enhanced
    username admin
    password admin
    <table>
        table logmessage
        column_mapping 'miologid:miologid,timestamputc:timestamputc,messageid:messageid,requestid:requestid,name,messagetype,isoutbound,ismetamessage,contents:contents,contentshash:contentshash,priority:priority,status:status,statusdescription:statusdescription,channelsource:channelsource,channeladapter:channeladapter,messagechannel:messagechannel,destinationchannelsource:destinationchannelsource,destinationadapter:destinationadapter,serializedmessage:serializedmessage'
    </table>
    flush_interval 1s
</match>
akostadinov commented 3 years ago

@harsh288 , not a fluentd expert. Perhaps try to find support in fluentd community.