Andrew Channels Dexter Pinion

Wherein I write some stuff that you may like to read. Or not, its up to you really.

March 27, 2003

Python UK Conference 2003

Is on next week. I'm going, are you?

For information go to the official site. Whilst you are there have a look at the schedule and see what you will be missing if you don't go.

Posted by Andy Todd at 10:42 AM | Comments (1)

March 10, 2003

Oracle v SQL Server, Part 8

The subject of todays post is updating several columns at once. Whilst this is possible in T-SQL I can't find a way to do this with a sub-query. Its quite simple in Oracle;

UPDATE tableA
SET (columna, columnb) =
    ( SELECT sum(valueA), count(valueB)
      FROM tableB
      WHERE tableB.foreignKey = tableA.key )

But when I try it in SQL Server all I get is an error message stating that An aggregate may not appear in the set list of an UPDATE statement.

Any suggestions?

Posted by Andy Todd at 03:24 PM | Comments (0)

March 07, 2003

Logging in Python

I have started to convert all of my code from using "print" debug statements to some more industrial strength logging. Rather than re-invent the wheel I've been using the logging module which will be included in Python 2.3.

It is a joy and a wonder. But the module and its documentation are a little bit on the complicated side. Which is right and proper as it is an industrial strength solution. I am a simple soul though, and generally just want one log per application writing to a file. After a little experimentation I have come up with my own logging function which hides the complexity of the logging module. I thought I would share it with you;

import logging
def log(logName, fileName):
    "Instantiate logName and make sure its output is written to fileName"
    logging.basicConfig()
    myLog = logging.getLogger(logName)
    myLog.setLevel(logging.INFO)
    # Define the handler and formmatter
    myHandler = logging.FileHandler(fileName, "w")
    myFormatter = logging.Formatter("%(asctime)s - %(levelname)-5s : %(message)s","%Y-%m-%d %H:%M:%S")
    # Attach the formatter to the handler and the handler to the log
    myHandler.setFormatter(myFormatter)
    myLog.addHandler(myHandler)
    return myLog

Which probably deserves a little explanation. The basic object we need to play with is a logger, which we get by calling getLogger. But, and this is a little unclear in the documentation, it will only write to standard output unless you attach a FileHandler object to it.

In turn, if you want to change the default message format (which I do) you have to attach a Formatter object to the FileHandler.

A quick trap for young players is the default logging level. This is set to WARN. I created my logger and started sending it INFO messages and was rather perplexed when nothing appeared. Until I guessed the logging level default. Which I couldn't easily find in the documentation. I tend to the verbose so I set the output level to INFO by default. My application code is then free to change it of course.

Posted by Andy Todd at 05:27 PM | Comments (1)