Hello.

I don't know why but the problematic version uses bytes as keys in the params
dictionary (e.g. b'batch_id') whereas the working version uses strings (e.g.
'batch_id'). I am not a Python 3 expert but I think that the two types are
distinct and thus the search for a string fails. This would also explain why the
column in the error changes - because dictionaries are nondeterministic.
Whatever key is searched for first will become the culprit.

Note however that these are just my assumptions...

HTH,

L.


On 28.7.2015 18:08, Bob Ternosky wrote:
> That did it.
> 
> 2015-07-28 12:06:16,283 INFO sqlalchemy.engine.base.Engine INSERT INTO
> corp.test_table (batch_id, batch_type, scheduled_date, status, emp_id, 
> bill_per,
> label, log_file, debug_file, completed_date) VALUES (:batch_id, :batch_type,
> :scheduled_date, :status, :emp_id, :bill_per, :label, :log_file, :debug_file,
> :completed_date)
> 2015-07-28 12:06:16,283 INFO sqlalchemy.engine.base.Engine {'log_file': None,
> 'batch_id': 999999, 'debug_file': None, 'scheduled_date':
> datetime.datetime(2015, 7, 28, 12, 6, 16, 282779), 'label': 'Testing insert',
> 'batch_type': 1, 'bill_per': 201501, 'status': 0, 'completed_date': None,
> 'emp_id': 8329}
> 2015-07-28 12:06:16,311 INFO sqlalchemy.engine.base.Engine COMMIT
> 
> You just saved my sanity.
> 
> Thanks a million!
> 
> And thanks to Jonathan Vanasco, your suggestions didn't work, but I learned a
> few new settings.
> 
> On Tuesday, July 28, 2015 at 11:54:14 AM UTC-4, Michael Bayer wrote:
> 
>     Just curious, can you try out cx_Oracle 5.1.3?   I've seen some problems
>     reported with Py3K and cx_Oracle 5.2.
> 
>     On 7/28/15 11:17 AM, Bob Ternosky wrote:
>>     I'm new to SQLAlchemy and have been playing with it for a week. I've got
>>     many SELECT based pieces working and exercising properly, but have hit a
>>     huge wall when trying to test inserts. Worse, what's happening makes no
>>     sense at all.
>>     This will hopefully contain the full set of information needed. Any help
>>     would be greatly appreciated.
>>
>>     The summary: When running a simple test insert it will fail with the 
>> error:
>>
>>        cx_Oracle.IntegrityError: ORA-01400: cannot insert NULL into
>>     ("CORP"."TEST_TABLE"."XXX")
>>
>>     where XXX changes just about every time I run the insert statement - with
>>     identical data.
>>
>>     My machine is running Linux Mint 17.2 64-bit
>>
>>     Software:
>>     * Python 3.4.0 (with virtualenv)
>>     * SQLAlchemy 1.0.7
>>     * cx_Oracle 5.2
>>
>>     Connecting to an Oracle 9i (9.2.0.6.0) database (joys of legacy systems).
>>     Using Oracle Instant Client 11.2.0 libraries
>>
>>     An Oracle "description" of the table (the table is empty):
>>
>>     > desc test_table
>>     BATCH_ID       NOT NULL NUMBER(10,0)
>>     BATCH_TYPE     NOT NULL NUMBER(2,0) 
>>     SCHEDULED_DATE NOT NULL DATE        
>>     STATUS         NOT NULL NUMBER(1,0) 
>>     EMP_ID         NOT NULL NUMBER(10,0)
>>     BILL_PER       NOT NULL NUMBER(6,0) 
>>     LABEL          NOT NULL VARCHAR2(128)
>>     LOG_FILE       NULL     VARCHAR2(256)
>>     DEBUG_FILE     NULL     VARCHAR2(256)
>>     COMPLETED_DATE NULL     DATE        
>>
>>     The table resides in the "CORP" schema.
>>
>>
>>
>>     Test script named: isolated.py
>>
>>     ----
>>     # isolated.py
>>     import argparse
>>     import datetime
>>
>>     from sqlalchemy import Column, create_engine, DateTime, insert, MetaData,
>>     Numeric, String, Table
>>
>>     # Declare insert test table
>>     metadata = MetaData()
>>     t_test_table = Table(
>>         'test_table', metadata,
>>         Column('batch_id', Numeric(9, 0, asdecimal=False), primary_key=True),
>>         Column('batch_type', Numeric(2, 0, asdecimal=False), nullable=False),
>>         Column('scheduled_date', DateTime, nullable=False),
>>         Column('status', Numeric(1, 0, asdecimal=False), nullable=False),
>>         Column('emp_id', Numeric(10, 0, asdecimal=False), nullable=False),
>>         Column('bill_per', Numeric(6, 0, asdecimal=False), nullable=False),
>>         Column('label', String(128), nullable=False),
>>         Column('log_file', String(256)),
>>         Column('debug_file', String(256)),
>>         Column('completed_date', DateTime),
>>         schema='corp'
>>     )
>>
>>     # Oracle Credentials
>>     USER   = 'REDACTED'
>>     PASSWD = 'REDACTED'
>>     SID    = 'REDACTED'
>>
>>     ###################
>>     # Main
>>     ###################
>>     parser = argparse.ArgumentParser(description = 'Test SQLAlchemy Insert')
>>     parser.add_argument('-c', '--cxoracle', dest = 'cxoracle', action =
>>     'store_true',
>>                         required = False, default = False, help = 'Use
>>     oracle+cx_oracle engine')
>>     parser.add_argument('-o', '--oracle', dest = 'oracle', action = 
>> 'store_true',
>>                         required = False, default = False, help = 'Use oracle
>>     only engine')
>>
>>     args = parser.parse_args()
>>     if not args.cxoracle and not args.oracle:
>>         parser.error("You must provide one of: [-c] [-o]")
>>
>>     # Pick an Oracle connection method
>>     if args.cxoracle:
>>         LIBRARY = 'oracle+cx_oracle'
>>     else:
>>         LIBRARY = 'oracle'
>>
>>     engine = create_engine('{}://{}:{}@{}'.format(LIBRARY, USER, PASSWD, 
>> SID),
>>     echo = True)
>>     conn = engine.connect()
>>
>>     values = dict(batch_id       = 999999,
>>                   batch_type     = 1,
>>                   scheduled_date = datetime.datetime.now(),
>>                   status         = 0,
>>                   emp_id         = 8329,
>>                   bill_per       = 201501,
>>                   label          = "Testing insert",
>>                   log_file       = None,
>>                   debug_file     = None,
>>                   completed_date = None)
>>
>>     tbl = t_test_table
>>     ins = tbl.insert().values(values)
>>     result = conn.execute(ins)
>>     print(result)
>>
>>     # Cleanup
>>     conn.close()
>>     engine.dispose()
>>
>>
>>     -----
>>
>>     I tried to isolate cx_Oracle vs basic Oracle, but no luck. If I run the
>>     script (with either -c or -o) I get the error message about the NULL
>>     violation. If I run it twice in a row, I get the same message, but the
>>     column changes. I've gotten batch_id, batch_type, status, emp_id,
>>     scheduled_date.
>>
>>     I've added some debug output to SQLAlchemy's "do_execute" method in
>>     "python3.4/site-packages/sqlalchemy/engine/default.py:
>>
>>        def do_execute(self, cursor, statement, parameters, context=None):
>>     +        print("*" *70)
>>     +       print(cursor)
>>     +        print(statement)
>>     +       print(parameters)
>>     +        print(context)
>>     +        print("*" *70)
>>             cursor.execute(statement, parameters)
>>
>>
>>     Here is the output of 2 consecutive runs against an empty table:
>>
>>
>>     (venv)[bash]$ python isolated.py -c
>>     2015-07-28 11:12:40,599 INFO sqlalchemy.engine.base.Engine b'SELECT USER
>>     FROM DUAL'
>>     2015-07-28 11:12:40,599 INFO sqlalchemy.engine.base.Engine {}
>>     **********************************************************************
>>     <cx_Oracle.Cursor on <cx_Oracle.Connection to USER@DB>>
>>     b'SELECT USER FROM DUAL'
>>     {}
>>     <sqlalchemy.dialects.oracle.cx_oracle.OracleExecutionContext_cx_oracle
>>     object at 0x7f6dda491a90>
>>     **********************************************************************
>>     2015-07-28 11:12:40,654 INFO sqlalchemy.engine.base.Engine SELECT
>>     CAST('test plain returns' AS VARCHAR(60 CHAR)) AS anon_1 FROM DUAL
>>     2015-07-28 11:12:40,654 INFO sqlalchemy.engine.base.Engine {}
>>     **********************************************************************
>>     <cx_Oracle.Cursor on <cx_Oracle.Connection to USER@DB>>
>>     SELECT CAST('test plain returns' AS VARCHAR(60 CHAR)) AS anon_1 FROM DUAL
>>     {}
>>     None
>>     **********************************************************************
>>     2015-07-28 11:12:40,708 INFO sqlalchemy.engine.base.Engine SELECT
>>     CAST('test unicode returns' AS NVARCHAR2(60)) AS anon_1 FROM DUAL
>>     2015-07-28 11:12:40,708 INFO sqlalchemy.engine.base.Engine {}
>>     **********************************************************************
>>     <cx_Oracle.Cursor on <cx_Oracle.Connection to USER@DB>>
>>     SELECT CAST('test unicode returns' AS NVARCHAR2(60)) AS anon_1 FROM DUAL
>>     {}
>>     None
>>     **********************************************************************
>>     2015-07-28 11:12:40,844 INFO sqlalchemy.engine.base.Engine b'INSERT INTO
>>     corp.test_table (batch_id, batch_type, scheduled_date, status, emp_id,
>>     bill_per, label, log_file, debug_file, completed_date) VALUES (:batch_id,
>>     :batch_type, :scheduled_date, :status, :emp_id, :bill_per, :label,
>>     :log_file, :debug_file, :completed_date)'
>>     2015-07-28 11:12:40,844 INFO sqlalchemy.engine.base.Engine {b'bill_per':
>>     201501, b'batch_type': 1, b'status': 0, b'scheduled_date':
>>     datetime.datetime(2015, 7, 28, 11, 12, 40, 843806), b'debug_file': None,
>>     b'log_file': None, b'label': 'Testing insert', b'completed_date': None,
>>     b'emp_id': 8329, b'batch_id': 999999}
>>     **********************************************************************
>>     <cx_Oracle.Cursor on <cx_Oracle.Connection to USER@DB>>
>>     b'INSERT INTO corp.test_table (batch_id, batch_type, scheduled_date,
>>     status, emp_id, bill_per, label, log_file, debug_file, completed_date)
>>     VALUES (:batch_id, :batch_type, :scheduled_date, :status, :emp_id,
>>     :bill_per, :label, :log_file, :debug_file, :completed_date)'
>>     {b'bill_per': 201501, b'batch_type': 1, b'status': 0, b'scheduled_date':
>>     datetime.datetime(2015, 7, 28, 11, 12, 40, 843806), b'debug_file': None,
>>     b'log_file': None, b'label': 'Testing insert', b'completed_date': None,
>>     b'emp_id': 8329, b'batch_id': 999999}
>>     <sqlalchemy.dialects.oracle.cx_oracle.OracleExecutionContext_cx_oracle
>>     object at 0x7f6dd188e3c8>
>>     **********************************************************************
>>     2015-07-28 11:12:40,900 INFO sqlalchemy.engine.base.Engine ROLLBACK
>>     Traceback (most recent call last):
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1139, in _execute_context
>>         context)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/default.py",
>>     line 456, in do_execute
>>         cursor.execute(statement, parameters)
>>     cx_Oracle.IntegrityError: ORA-01400: cannot insert NULL into
>>     ("CORP"."TEST_TABLE"."BATCH_ID")
>>
>>
>>     The above exception was the direct cause of the following exception:
>>
>>     Traceback (most recent call last):
>>       File "isolated.py", line 68, in <module>
>>         result = conn.execute(ins)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 914, in execute
>>         return meth(self, multiparams, params)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/sql/elements.py",
>>     line 323, in _execute_on_connection
>>         return connection._execute_clauseelement(self, multiparams, params)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1010, in _execute_clauseelement
>>         compiled_sql, distilled_params
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1146, in _execute_context
>>         context)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1341, in _handle_dbapi_exception
>>         exc_info
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py",
>>     line 188, in raise_from_cause
>>         reraise(type(exception), exception, tb=exc_tb, cause=exc_value)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py",
>>     line 181, in reraise
>>         raise value.with_traceback(tb)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1139, in _execute_context
>>         context)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/default.py",
>>     line 456, in do_execute
>>         cursor.execute(statement, parameters)
>>     sqlalchemy.exc.IntegrityError: (cx_Oracle.IntegrityError) ORA-01400:
>>     cannot insert NULL into ("CORP"."TEST_TABLE"."BATCH_ID")
>>      [SQL: b'INSERT INTO corp.test_table (batch_id, batch_type,
>>     scheduled_date, status, emp_id, bill_per, label, log_file, debug_file,
>>     completed_date) VALUES (:batch_id, :batch_type, :scheduled_date, :status,
>>     :emp_id, :bill_per, :label, :log_file, :debug_file, :completed_date)']
>>     [parameters: {b'bill_per': 201501, b'batch_type': 1, b'status': 0,
>>     b'scheduled_date': datetime.datetime(2015, 7, 28, 11, 12, 40, 843806),
>>     b'debug_file': None, b'log_file': None, b'label': 'Testing insert',
>>     b'completed_date': None, b'emp_id': 8329, b'batch_id': 999999}]
>>
>>
>>
>>     (venv)[bash]$ python isolated.py -c
>>     2015-07-28 11:12:43,349 INFO sqlalchemy.engine.base.Engine b'SELECT USER
>>     FROM DUAL'
>>     2015-07-28 11:12:43,350 INFO sqlalchemy.engine.base.Engine {}
>>     **********************************************************************
>>     <cx_Oracle.Cursor on <cx_Oracle.Connection to USER@DB>>
>>     b'SELECT USER FROM DUAL'
>>     {}
>>     <sqlalchemy.dialects.oracle.cx_oracle.OracleExecutionContext_cx_oracle
>>     object at 0x7f726fa76ac8>
>>     **********************************************************************
>>     2015-07-28 11:12:43,405 INFO sqlalchemy.engine.base.Engine SELECT
>>     CAST('test plain returns' AS VARCHAR(60 CHAR)) AS anon_1 FROM DUAL
>>     2015-07-28 11:12:43,405 INFO sqlalchemy.engine.base.Engine {}
>>     **********************************************************************
>>     <cx_Oracle.Cursor on <cx_Oracle.Connection to USER@DB>>
>>     SELECT CAST('test plain returns' AS VARCHAR(60 CHAR)) AS anon_1 FROM DUAL
>>     {}
>>     None
>>     **********************************************************************
>>     2015-07-28 11:12:43,459 INFO sqlalchemy.engine.base.Engine SELECT
>>     CAST('test unicode returns' AS NVARCHAR2(60)) AS anon_1 FROM DUAL
>>     2015-07-28 11:12:43,459 INFO sqlalchemy.engine.base.Engine {}
>>     **********************************************************************
>>     <cx_Oracle.Cursor on <cx_Oracle.Connection to USER@DB>>
>>     SELECT CAST('test unicode returns' AS NVARCHAR2(60)) AS anon_1 FROM DUAL
>>     {}
>>     None
>>     **********************************************************************
>>     2015-07-28 11:12:43,614 INFO sqlalchemy.engine.base.Engine b'INSERT INTO
>>     corp.test_table (batch_id, batch_type, scheduled_date, status, emp_id,
>>     bill_per, label, log_file, debug_file, completed_date) VALUES (:batch_id,
>>     :batch_type, :scheduled_date, :status, :emp_id, :bill_per, :label,
>>     :log_file, :debug_file, :completed_date)'
>>     2015-07-28 11:12:43,614 INFO sqlalchemy.engine.base.Engine {b'log_file':
>>     None, b'status': 0, b'batch_type': 1, b'completed_date': None, b'emp_id':
>>     8329, b'scheduled_date': datetime.datetime(2015, 7, 28, 11, 12, 43,
>>     613744), b'label': 'Testing insert', b'debug_file': None, b'bill_per':
>>     201501, b'batch_id': 999999}
>>     **********************************************************************
>>     <cx_Oracle.Cursor on <cx_Oracle.Connection to USER@DB>>
>>     b'INSERT INTO corp.test_table (batch_id, batch_type, scheduled_date,
>>     status, emp_id, bill_per, label, log_file, debug_file, completed_date)
>>     VALUES (:batch_id, :batch_type, :scheduled_date, :status, :emp_id,
>>     :bill_per, :label, :log_file, :debug_file, :completed_date)'
>>     {b'log_file': None, b'status': 0, b'batch_type': 1, b'completed_date':
>>     None, b'emp_id': 8329, b'scheduled_date': datetime.datetime(2015, 7, 28,
>>     11, 12, 43, 613744), b'label': 'Testing insert', b'debug_file': None,
>>     b'bill_per': 201501, b'batch_id': 999999}
>>     <sqlalchemy.dialects.oracle.cx_oracle.OracleExecutionContext_cx_oracle
>>     object at 0x7f7266e733c8>
>>     **********************************************************************
>>     2015-07-28 11:12:43,669 INFO sqlalchemy.engine.base.Engine ROLLBACK
>>     Traceback (most recent call last):
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1139, in _execute_context
>>         context)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/default.py",
>>     line 456, in do_execute
>>         cursor.execute(statement, parameters)
>>     cx_Oracle.IntegrityError: ORA-01400: cannot insert NULL into
>>     ("CORP"."TEST_TABLE"."BILL_PER")
>>
>>
>>     The above exception was the direct cause of the following exception:
>>
>>     Traceback (most recent call last):
>>       File "isolated.py", line 68, in <module>
>>         result = conn.execute(ins)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 914, in execute
>>         return meth(self, multiparams, params)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/sql/elements.py",
>>     line 323, in _execute_on_connection
>>         return connection._execute_clauseelement(self, multiparams, params)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1010, in _execute_clauseelement
>>         compiled_sql, distilled_params
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1146, in _execute_context
>>         context)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1341, in _handle_dbapi_exception
>>         exc_info
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py",
>>     line 188, in raise_from_cause
>>         reraise(type(exception), exception, tb=exc_tb, cause=exc_value)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py",
>>     line 181, in reraise
>>         raise value.with_traceback(tb)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py",
>>     line 1139, in _execute_context
>>         context)
>>       File
>>     
>> "/home/rternosky/src/git/pluto/venv/lib/python3.4/site-packages/sqlalchemy/engine/default.py",
>>     line 456, in do_execute
>>         cursor.execute(statement, parameters)
>>     sqlalchemy.exc.IntegrityError: (cx_Oracle.IntegrityError) ORA-01400:
>>     cannot insert NULL into ("CORP"."TEST_TABLE"."BILL_PER")
>>      [SQL: b'INSERT INTO corp.test_table (batch_id, batch_type,
>>     scheduled_date, status, emp_id, bill_per, label, log_file, debug_file,
>>     completed_date) VALUES (:batch_id, :batch_type, :scheduled_date, :status,
>>     :emp_id, :bill_per, :label, :log_file, :debug_file, :completed_date)']
>>     [parameters: {b'log_file': None, b'status': 0, b'batch_type': 1,
>>     b'completed_date': None, b'emp_id': 8329, b'scheduled_date':
>>     datetime.datetime(2015, 7, 28, 11, 12, 43, 613744), b'label': 'Testing
>>     insert', b'debug_file': None, b'bill_per': 201501, b'batch_id': 999999}]
>>
>>
>>     -- 
>>     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/d/optout.
> 
> -- 
> 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 http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.


-- 
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