tags:

views:

293

answers:

1

I'm loading some python code from a database (it's doing dynamic mapping of values that I can change at runtime without a code redeploy).

In my code, I'm doing this to execute the database code:

if lMapping:
  print lMapping
  exec lMapping
  lValue = mapping(lValue, lCsvRow)

and here's the value of lMapping:

def mapping(pValue, pCsvRow):
  lInterimStatus = pCsvRow[5]
  lOutComeStatus = pCsvRow[6]

  if len(lInterimStatus) == 0:
    lStatus = lOutComeStatus
  else:
    lStatus = lInterimStatus

  lStatus = lStatus.lower()

  PRIMARY_STATUS_MAPPINGS = {
    'completed with lender' : '4828',
    'not taken up' : '4827',
    'declined across all lenders' : '4726',
    'declined broker duplicate' : '4726',
    'pending' : '4725',
    'pending (in progress with broker)' : '4725',
    'pending (in progress with lender)' : '4725',
    'lender accept in principle' : '4827',
    'lender decline duplicate' : '4743',
    'lender decline post code not supported' : '4743',
    'lender decline score fail' : '4743',
    'lender decline policy fail' : '4743',
    'lender decline no client contact' : '4743',
    'lender decline general' : '4743',
    'lender decline bad data' : '4743',
  }

  return PRIMARY_STATUS_MAPPINGS[lStatus]

Whenever I do this I'm getting a syntax error on the exec line, I can't work out why:

(<type 'exceptions.SyntaxError'>:invalid syntax (<string>, line 1)

UPDATE

It works if I write the code from the database to a file first:

print lMapping
lFile = open('/mapping.py','w')
lFile.write(lMapping)
lFile.close()
lReadFile = open('/mapping.py')
exec lReadFile
lValue = mapping(lValue, lCsvRow)
A: 

Do you BLOB or other binary type column to store code? Otherwise database might change line endings and exec will break with SyntaxError:

>>> s='''\
... print 'ok'
... '''
>>> s
"print 'ok'\n"
>>> exec s
ok
>>> exec s.replace('\n', '\r\n')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    print 'ok'
              ^
SyntaxError: invalid syntax

Update: Writing to file on Windows in text mode will change line endings to platform native ones. Another way to normalize them is:

lMapping = os.linesep.join(lMapping.splitlines())
Denis Otkidach
The table was created by django, NVARCHAR2(2000). It's an oracle database.
Tim
It's down to the line ends as you suggested, but your solution would only work where os.linesep was '\n'. I'm developing on windows and deploying on solaris, so I fixed it by doing lMapping = lMapping.replace('\r\n','\n'). Thanks.
Tim