Python’s sys.stdout loses encoding

When you use Python with sys.stdout you might run into a problem where sys.stdout.encoding suddenly becomes None. This happens due to the fact that upon using a pipe or redirection, at least under Unix, it falls back to not knowing anything about the target. In order to work around this you can add a fallback to use locale.getpreferredencoding(). So if you use encode() on a string you can do something like:

from locale import getpreferredencoding

text = u"Something special"

print text.encode(sys.stdout.encoding or getpreferredencoding() or 'ascii', 'replace')

This is how we currently use it within Babel as well for printing the locale list.

SQLAlchemy and simple WHERE clauses using AND

These posts use code from the Trac project. I’m using the question mark notation for in-place variable substitution, this is where you normally use either direct variables or an indirection mechanism.

If you have done SQL before you are familiar with the syntax such as:

SELECT name FROM auth_cookie WHERE cookie = ? AND ipnr = ?;

So, how does one do this with SQLAlchemy?

With SQLAlchemy (SA in short) you first declare a schema within Python:

auth_cookie = Table('auth_cookie', metadata,
        Column('cookie', String, primary_key=True),
        Column('name', String, primary_key=True),
        Column('ipnr', String, primary_key=True),
        Column('time', Integer))

Next you import this schema (living within Trac as trac/db/schema.py) as follows:

from trac.db.schema import auth_cookie

This allows direct manipulation using direct calls to auth_cookie. So for a SQL select we need to extend our code as follows:

from sqlalchemy import select

This allows us to build an almost equivalent statement as follows:

statement = select([auth_cookie.c.name], auth_cookie.c.cookie==?)

To add the AND clause SA has a very simple function to add into your code:

from sqlalchemy import and_, select

This allows us to extend the previous statement as such:

statement = select([auth_cookie.c.name], and_(auth_cookie.c.cookie==?, auth_cookie.c.ipnr==?)

Similarly there’s an or_() function as well, which works exactly the same.

Now the difficulty arose due to the fact this SQL query changed its WHERE-clause depending on an if/else. The regular case was the first statement we created, the other case added the cookie’s IP number into the equation. So how to deal with that?

statement = select([auth_cookie.c.name], auth_cookie.c.cookie==?)
if self.check_ip:
    statement.append_whereclause(and_(auth_cookie.c.ipnr==?))

As you can see, depending on whether or not check_ip is set it changes the statement in-place and expands the WHERE-clause with an AND for ipnr.

FreeBSD, SQLite, FTS2 and SQLAlchemy

I was trying to use the SQLite 3.4.1 installed port with Python and SQLAlchemy and the moment I wanted to create a table within the database Python crashed.

After a bunch of debugging it turns out that enabling the FTS2 option of the port causes these crashes. The sqlite3Fts2InitHashTable() call is where it fails. I notified the port maintainer and in the mean time rebuilt without FTS2.

Beware of the fury of the patient man…

Some of these days just start whacked.

Manager asks me to overlook a CV of the guy who’s going to replace me. Sure, no problem. So I find the guy alright and now I have to help in interviewing him? Uhhh, this is funny. Not that usual in the Netherlands to do this…

Bored out of my mind, thankfully I can put the time to good use. Almost up to date on all episodes of Uzumaki Naruto.

Right now converting Amos’ script from elisp to Python. Going nicely thus far.

The weather makes me want to put on some Muse or likewise bands… Although I was listening to UK Punjabi remixes in the car on my way to work…