This great. It is a good solution for now and can be used as example of 
similar solutions for other adapters.

On Wednesday, 5 August 2015 12:17:49 UTC-5, Boris Aramis Aguilar Rodríguez 
wrote:
>
> Hi :)
>
> I've just managed to fix my issue by adding/modifying a couple of methods 
> of the *pydal.adapters.oracle.OracleAdapter class*; everything seems to 
> be working for me
>
>     def _insert(self, table, fields):
>         table_rname = table.sqlsafe
>         if fields:
>             keys = ','.join(f.sqlsafe_name for f, v in fields)
>             r_values = dict()
>             def value_man(f, v, r_values):
>                 if f.type is 'text':
>                     r_values[':' + f.sqlsafe_name] = self.expand(v, f.type
> )
>                     return ':' + f.sqlsafe_name
>                 else:
>                     return self.expand(v, f.type)
>             values = ','.join(value_man(f, v, r_values) for f, v in fields
> )
>             return ('INSERT INTO %s(%s) VALUES (%s);' % (table_rname, keys
> , values), r_values)
>         else:
>             return (self._insert_empty(table), None)
>
>     def insert(self, table, fields):
>         query, values = self._insert(table,fields)
>         try:
>             if not values:
>                 self.execute(query)
>             else:
>                 self.execute(query, values)
>         except Exception:
>             e = sys.exc_info()[1]
>             if hasattr(table,'_on_insert_error'):
>                 return table._on_insert_error(table,fields,e)
>             raise e
>         if hasattr(table, '_primarykey'):
>             mydict = dict([(k[0].name, k[1]) for k in fields if k[0].name 
> in table._primarykey])
>             if mydict != {}:
>                 return mydict
>         id = self.lastrowid(table)
>         if hasattr(table, '_primarykey') and len(table._primarykey) == 1:
>             id = {table._primarykey[0]: id}
>         if not isinstance(id, (int, long)):
>             return id
>         rid = Reference(id)
>         (rid._table, rid._record) = (table, None)
>         return rid
>
>
>
> El martes, 4 de agosto de 2015, 1:00:59 (UTC-6), Niphlod escribió:
>>
>> ok, we were discussing the same thing over at pydal's repo to address 
>> another issue, that is closely related . 
>> https://github.com/web2py/pydal/issues/155
>>
>> On Monday, August 3, 2015 at 8:57:44 PM UTC+2, Boris Aramis Aguilar 
>> Rodríguez wrote:
>>>
>>> I've found the following:
>>>
>>> To insert a text using the cx_Oracle driver directly if you do something 
>>> like
>>>
>>> import cx_Oracle
>>> connection = cx_Oracle.connect('connectionstring')
>>>
>>> cursor = connection.cursor()
>>>
>>> p = ''
>>> for i in range(1,10000):
>>>   p += str(i)
>>>
>>> sss = "INSERT INTO 
>>> ipvpn_route_table(read_datetime,ip_vpn,route_table,destinations) VALUES 
>>> (NULL,6,'" + p + "','" + p + "')"
>>> cursor.execute(sss)
>>>
>>> It fails with the same error as the web2py traceback
>>>
>>> DatabaseError: ORA-01704: string literal too long
>>>
>>> The correct way to do it is by passing it with parameters (and it works 
>>> with any ammount of characters below 4GB of clob data) as follows:
>>>
>>> import cx_Oracle
>>> connection = cx_Oracle.connect('... connection string')
>>>
>>> cursor = connection.cursor()
>>>
>>> p = ''
>>> for i in range(1,10000):
>>>   p += str(i)
>>>
>>> sss = "INSERT INTO 
>>> ipvpn_route_table(read_datetime,ip_vpn,route_table,destinations) VALUES 
>>> (NULL,6,:FOO,:BAR)"
>>> cursor.execute(sss, FOO=p, BAR=p)
>>>
>>>
>>>
>>> El lunes, 3 de agosto de 2015, 9:51:16 (UTC-6), Boris Aramis Aguilar 
>>> Rodríguez escribió:
>>>>
>>>> Hi,
>>>>
>>>> I've been currently working with Oracle as a database backend, I have 
>>>> found one issue that I highly suspect has to do with the DAL Adapter; when 
>>>> you use web2py text fields they get mapped into CLOB with oracle database 
>>>> backend (as you can see on the OracleAdapter code) the issue is dealing 
>>>> with text longer than 4k characters. Oracle doesn't support a typical 
>>>> insert with more than 4k characters dealing with a CLOB data type, because 
>>>> it treats it as a string and strings can't be more than 4k characters 
>>>> long. 
>>>> So for example dealing with a table like
>>>>
>>>> db.define_table('atable', Field('longtext', 'text'))
>>>>
>>>> db.atable.insert(longtext=somelongtext) #This fails with the following 
>>>> exception
>>>>
>>>>   File "/var/www/web2py/gluon/packages/dal/pydal/objects.py", line 691, in 
>>>> insert
>>>>     ret = self._db._adapter.insert(self, self._listify(fields))
>>>>   File "/var/www/web2py/gluon/packages/dal/pydal/adapters/base.py", line 
>>>> 731, in insert
>>>>     raise e
>>>> DatabaseError: ORA-01704: string literal too long
>>>>
>>>> And reading trough several forums I found that this error appears on CLOB 
>>>> insertion when you do a tipycal insert. 
>>>> https://community.oracle.com/thread/1068414?start=0&tstart=0
>>>>
>>>> So i guess OracleAdapter is trying to achieve a typical insertion when it 
>>>> shouldn't as it has to deal with CLOB logic.
>>>>
>>>> I think I could fix the problem but I'm not really sure if someone can 
>>>> help me out with a hint of some kind.
>>>>
>>>> Thanks!
>>>>
>>>>
>>>>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to