September 2006 archive

Django Schema Evolution

Django does not yet suppot automatic database schema migration, or evolution, as some like to call it. What that means is, if you create a project with a nice model, defined in Python in the Django way, and you later decide to add or drop a field, for example, there is not automatic way for Django to go modify the corresponding database tables. You have to go run the SQL commands yourself, which, up until this point in your Django life, you've never had to do. All you needed to know was Python. I know, a real bummer.

I am working on a little application where I did just that. I wrote something up that was cool and useful and all, but after using for a couple weeks, I realized it could be even cooler with a couple more tables and a couple more relations. Now, how to modify my database? Turns out it wasn't too scary.

Django puts a nice script called manage.py in the top level of your project that can do some cool stuff. If you type ./manage.py sqlall appname it outputs all the "create table", "create index", "alter table", etc. commands that it will use to create the tables for you model.

So, to do this, I checked out my code from svn, modified settings.py to use a new database, so as not to mess with my current one, and went to work modifying my model. When it was all done and everything was working on this pseudo branch, I ran ./manage.py sqlall appname on both the current and this new version of my application and put the output of each side-by-side in my emacs frame and ran ediff-buffers. It was easy to see what tables, columns, and indexes I needed to add. Turns out the SQL is pretty straightforward from there. For example, I have this table, from the output of sqlall:

CREATE TABLE "organizer_person" (
    "id" serial NOT NULL PRIMARY KEY,
    "firstname" varchar(200) NOT NULL,
    "lastname" varchar(200) NOT NULL,
    "email" varchar(75) NULL,
    "phone_number" varchar(20) NULL,
    "address" varchar(100) NULL,
    "city" varchar(50) NULL,
    "state" varchar(2) NULL,
    "zipcode" integer CHECK ("zipcode" >= 0) NULL
);

The address stuff is what I newly added. I ran psql databasename and did something like this:

ALTER TABLE organizer_person ADD COLUMN "zipcode" integer CHECK ("zipcode" >= 0) NULL;

for each of the new columns. Notice how after the "ADD COLUMN" you can just copy and paste the rest from the "CREATE TABLE" stuff above. To add a whole new table or an index it was even easier, just copy and paste the "CREATE TABLE" or "CREATE INDEX" stuff straight from the output of sqlall.

Lastly, in my case, I needed the permissions for my new tables added to the auth application's tables so my users could modify them with the Django admin application. For this, it turns out all you have to do is type ./manage.py syncdb and it adds to rows to the auth_permissions table for you automatically. Nice.

Posted by Bryan on September 11, 2006 | Filed under: Geek | 0 comments

Spanglish and Ears

Two unrelated bits of news. First of all, I forgot to mention one other thing we did on Isaac's birthday (it was getting late at night when I typed that up). We took Reece in to see the doctor because he's been pretty fussy (for Reece this is very strange, he's usually very mellow). It turns out he's followed in the footsteps of his older brothers and gotten an ear infection before turning three months old. After two days of antibiotics he's feeling much better.

The other bit of news is that Ily invited our neighbors from Guadalajara over, Alejandra and her son Paco, who is two. Micah and Paco had a great time playing, but Micah had a bit of trouble getting his friend's name right. When I got home from work, I heard all about how Taco came to play today.

Posted by Bryan on September 7, 2006 | Filed under: Family News | 0 comments

Summer's Last Hurrah

Ahh the last days of summer before school. We played hard this Labor Day weekend. Friday I took the day off and we went back to Andrew's cabin (my co-worker). The water in the reservoir was a bit colder this time, but we still had a great time. We forgot the camera again, unfortunately. The views of Mt. St. Helens and Mt. Adams are incredible up there. Next time.

Saturday we recovered a bit and did some shopping that needed to be done. Sunday was restful as well. Monday we joined the Labor Day crowds and tackled our favorite Columbia Gorge hike, Ponytail Falls (pictures from last time). It was Reece's first hike, and he slept in the front pack most of the way. Ily carried him. I had Micah in the backpack. He didn't want to hike at all, and he fell asleep part way through too. A hiking book I had for a while called this hike, "The most waterfall bang for your buck." You get to see three in less than three miles, and it's not a very steep climb at all. We love it.

Isaac went to his first day of school today. He said recess was his favorite part and this evening he asked me when he gets to do "real school" with homework. He asked when he gets to learn how to read too. I told him to ask his teacher. This reminds me, did I tell you about the time a few weeks ago when he did some division out of the blue? I was making pancakes one morning and he asked me how many I was going to make. I told him the recipe said there would be 12. He said, "hmm, four of us will be eating, so we each get 3." Wow, I thought. A few minutes later when I was done I informed him that I had actually made 16. "OK, we each get 4." he said. Just like that. He's a genius I tell you. Anyway, he's excited for school.

Lastly, we had cake and a few presents for Isaac's sixth birthday this evening. Nothing too exciting there. He got a t-ball stand and a boomerang (that he had begged his mom for the other day). We'll have to hurry and play with them lots before the rain starts up again.

Pictures, pictures, pictures.

Posted by Bryan on September 5, 2006 | Filed under: Family News | 2 comments

Backups and Cron

I'm making my backups more automated. I decided to use the simple backup tool that can be found under System -> Administration, but I configured it exactly how I had mondo configured, as far as which directories to back up and which to ignore. One tricky thing was, by default it wants to back stuff up to /var/backup. I wanted it to back stuff up to my other hard drive found at /mnt/home. The GUI has a place to set that, but it seemed to ignore my setting, so I just made /var/backup a symbolic link to /mnt/home/backup. Works fine.

The next thing was to set up a cron job to dump my postgresql databases to a file, and then that file can be backed up along with everything else. The first thing I changed was when cron jobs are run. I edited /etc/crontab and changed the second column, which is the hour column, from 6 (as in 6 AM) to 0 (as in midnight). From what I read, you don't have to do anything special for cron to pick up changes to /etc/crontab.

A little tangent here. I learned that there is good old cron, which runs a job only if the computer is on when that job is scheduled, and then there is anacron, which runs jobs whenever it can, apparently, to meet the broader scheduling criteria, such as daily, weekly, or monthly. It uses a separate program called run-parts to run scripts found in /etc/con.daily, /etc/cron.weekly, etc. run-parts puts timestamps in /var/spool/anacron/ to let anacron known when jobs were run last. It appears that on my Ubuntu Dapper Drake box, both cron and anacron run together? How? Well, /etc/crontab uses run-parts to run the same /etc/cron.* scripts that anacron does. Pretty tricky.

So, to add a postgresql-backup cron job, I just created a shell script in /etc/cron.daily called, postgresql-backup. I put the right shell commands in there, and I think that should do it.

One more thing I noticed poking around cron and /var. There is a cron script in cron.daily called standard. It backs up some important system files like /etc/password and /etc/shadow to /var/backups. That could come in handy some day for somebody, I'm sure.

Posted by Bryan on September 2, 2006 | Filed under: Geek | 0 comments

Topics

Highlights

Other Stuff

rss feed for latest comments Latest comments feed

What are these orange icons?

Search This Site

Archives


This site assembled by Bryan Murdock, using: