Archive for November, 2007

PostgreSQL, SQLAlchemy, Dropping all tables and sequences

Friday, November 23rd, 2007


I've been working in deployment scripts for my current project and sometimes I need to drop all the tables and sequences from the database so I can create everything from scratch. I had been doing a

 
DROP SCHEMA public CASCADE;
CREATE SCHEMA public AUTHORIZATION bob;
GRANT ALL ON SCHEMA public TO bob;
 

This was great but a little destructive and over the top. It removes stored procedures and triggers as well which isn't what I want. So I looked at the SQLAlchemy docs and there is a metadata command drop_all()

 
def drop_tables():
    metadata.drop_tables()
 

Unfortunately this doesn't CASCADE so this isn't going to work in cases where tables have foreign keys (which is most of the time). It also leaves sequences in place.

So I looked at dropping each table in turn with a cascade. So how do you get a list of tables and sequences in the database? I could hard code the names of the tables and sequences but that seemed a little poor.

It turns out that PostgreSQL has a set of views that expose the inner workings of your database and a few queries can give you all the information you need.

 
def get_table_list_from_db():
    """
    return a list of table names from the current
    databases public schema
    """
    sql="select table_name from information_schema.tables"\
        "where table_schema='public'"
    execute = metadata.execute
    return [name for (name, ) in execute(text(sql))]
 
def get_seq_list_from_db():
    """return a list of the sequence names from the current
       databases public schema
    """
    sql="select sequence_name from information_schema.sequences"\
        "where sequence_schema='public'"
    execute = metadata.execute
    return [name for (name, ) in execute(text(sql))]
 
def drop_all_tables_and_sequences():
    execute = metadata.execute
    for table in get_table_list_from_db():
        try:
            execute(text("DROP TABLE %s CASCADE" % table))
        except SQLError, e:
            print e
 
    for seq in get_seq_list_from_db():
        try:
            execute(text("DROP SEQUENCE %s CASCADE" % table))
        except SQLError, e:
            print e
 

The information_schema is full of interesting information. It's actually a 'view' of lower level database tables. You can find all sorts of performance and configuration information in there. Quite handy :) Here are some docs.

Good luck.

workingenv, easy_install, ez_setup… hmmm

Friday, November 23rd, 2007


Working with TurboGears is usually a breeze. But when it comes to installation thing never seem to go too well. Firstly do you run the tg_setup.py the project provides or easy_install TurboGears it? Why do you need to run the installer twice sometimes? There are answers in the mailing list to these questions but the fact these questions are asked gives me the willies.

I'm not having a go at the maintainers of the project. They are always extra helpful on the mailing list and to be fair if it really bothers me that much why don't I just fix it myself. I'm sad to say I can't be bothered, I've got more important things to do and I'm sure the maintainers have made the same decision.

Anyway, today I ran across a new one and couldn't find a solution via google so I'm offering up this snippet to the search engine in the sky.

After installing most of TurboGears I went to install Routes. I used easy_install but it didn't work.

 
easy_install "Routes >= 1.7"
Searching for Routes>=1.7
Reading http://pypi.python.org/simple/Routes/
Reading http://routes.groovie.org/
Best match: Routes 1.7.1
Downloading http://pypi.python.org/packages/source/R/Routes/
  Routes-1.7.1.tar.gz#md5=89cdc61ae803dc151c338ddd85551478
Processing Routes-1.7.1.tar.gz
Running Routes-1.7.1/setup.py -q bdist_egg --dist-dir
  /tmp/easy_install-6ZoHjg/Routes-1.7.1/egg-dist-tmp-GXYrHm
Traceback (most recent call last):
 
...
 
  File "/usr/local/tgmetalinfo/tgenv/lib/python2.5/
   setuptools-0.6c7-py2.5.egg/setuptools/sandbox.py", line 29, in <lambda>
    {'__file__':setup_script, '__name__':'__main__'}
  File "setup.py", line 1, in <module>
ImportError: No module named ez_setup
 

The first thing that struck me is that ez_setup is part of the setup tools package so how can it not be imported. To complicate things more I'm using workingenv which dicks about with your PYTHONPATH to create a sandbox.

After poking about on the easy_install site I found the answer in the docs. I created a file (in the current working directory) like this:

 
[easy_install]
 
# set the default location to install packages
install_dir = CWD/ENVIRONMENT FOLDER/lib/python2.5
 

where CWD and ENVIRONMENT FOLDER are replaced with your workingenv library path. Now the install works.

I think all of this has something to so with workingenv not creating a site-packages folder inside lib/python2.5 and something somewhere expecting it. Anyway, it all works for me now. Hope this helps.

PS: I know working env is deprecated in favour of virtualenv but I ran in to the same problem with virtualenv :(

Persuading Atheists

Tuesday, November 13th, 2007

It's really early in the morning so I'm a little cranky. While clicking around on my del.icio.us feed this article appeared: How to Persuade an Atheist to Become a Christian. Now normally I'm a pretty angry kind of guy and after only a few hours sleep and a single coffee I'm not the kind of atheist you want to fuck around with. I've got to say though, I really hope this article doesn't get taken down from wikiHow. Here are my blurry, mono-coffee, anti meridian reasons:

  1. It's quite frankly such a weak set of steps that it isn't going to do any harm.
  2. It's quite charming in an new testament, jesus loves you kind of a way.
  3. It does at least treat Atheists with some degree of respect although not a lot.
  4. I'm sure there are many many sites trying to achieve the reverse. In fact many Christians claim the whole secular movement (and thus the western world) is trying to turn Christians bad.
  5. Atheism as a movement was first galvanized by the french and as an Englishmen I'll do support anything that even remotely undermines the french ;-)

So are all atheists angry?

As an adjunct to this, here is a REALLY scary picture

9Lh0Jq
(It's from IT the movie and yes he is getting closer and if you look for too long he leaps out from the screen and persuades you to become a clown... Jesus christ!)

and a NOT so scary picture

Automated Build
(fear my automated build system... and my tiny penguin. Or maybe I have a normal sized penguin and a giant robot arm, calculator, mario mug, pens and desk... either way fear something or other... Jesus saves!)