Database newbie - Sound Software Engineering practice for DB

Justin Shaw wyojustin at hotmail.com
Tue Jan 21 21:07:22 EST 2003


It looks like you are on the right track.  Keep asking yourself these
questions.  I have interjected my thoughts throughout.
Justin

"Otto Tronarp" <otttr440 at student.liu.se> wrote in message
news:mailman.1043194598.32555.python-list at python.org...
> Hi,
>
> I'm a complete database newbie, the little I know I learned the last
> couple of hours when browsing the web, and have a couple of questions on
> what sound software engineering practice is when it comes to using
> databases.
>
> Say that I want to make an app that calculates some statistics of soccer
> matches in several different leagues. So I have the following SQL table:
> CREATE TABLE matches (date DATE,
>                       home_team VARCHAR(20),
>                       away_team VARCHAR(20),
>                       home_score INT,
>                       away_score INT,
>                       league_id VARCHAR(5));
>
> (BTW: Is it smart to have have all the matches from all leagues in the
> same table or should I have one matches table per league?)

Use the minimal number of tables such that no data is duplicated.   Filters
are easier to write than joins.  You have it right here.

<...snip...>

>
> But it doesn't look to good with all those "raw" SQL statements
> cluttered everywhere in the code, if I change the structure of the table
> I might need to change the code in a lot of places. So, I thought it was
> a good idea to hide it in a class, maybe something like this.
>
> class LeagueDB:
>     def __init__ (self, con, dbname):
>         self.con = con
>         self.dbname = dbname
>     def _newCursor(self):
>         cur = self.con.cursor()
>         #with MySQLdb I could use db.select_db but this
>         #doesn't look like a part of the DB2 API so....
>         cur.execute("""USE %s""" % self.dbname)
>         return cur
>
>     def getHomeMatches(self, team):
>         cur = self._newCursor()
>         cur.execute("""SELECT * from matches WHERE home_team="%s" """,
> team)
> return cur

I prefer to have the cursor passed in as an argument.  That way you can let
the database handle all of the permissions.  The users get assigned a
connection when they log in and you never have to worry about tracking them.

>
> But often I want different constraints on the query, like only matches
> before a specific date or in a specific time period, etc. I could do a
> getHomeMatchesBeforeDate(self, team, date),
> getHomeMatchesForTimePeriod(self, team, start_date, end_date) but it is
> pretty clumsy so I want something like getHomeMatches(self, team,
> constraints), any ideas how I could implement that in a smooth way?

Make the common thing easy and the uncommon possible.  I do this by writing
the common querries as you have with a couple of extra defaulted arguments:
fields='*' and where='1'.  Then your query becomes something like

sql = 'select %s from TABLE where %s' % (fields, where)

I am working on a python/MySQL spelling application currently that three
data layers and a GUI layer.  The data layers are:
1. database later (MySQL)
2. DB module -- class reprensentation of the database tables
3. SmartRow module -- class represention of the rows and relationships.

The application only interacts with the SmartRow module.  You can browse the
csv on our sourceforge project if you want to have a look.
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/spellquest/spellquest/spellqu
est/

>... Or
> am I completely off track and should use raw SQL queries all the time?

I think you are on the right track.  Try to keep the SQL isolated to a
module or two.

> Or is there another way?

I've seen a few projects that are supposed to automatically write the
interface to your db but I haven't tried the.  Check out the daily python
url (linked on python.org), I think I saw them there.

Good luck and let me know if you have any good ideas for SpellQuest






More information about the Python-list mailing list