[orm-devel] shh closed

Diedrich Vorberg orm-devel@mailman.tux4web.de
Fri, 17 Jan 2003 01:06:13 +0100


Hi Julio, nice to hear from you!

>I've tried yesterday to connect to the cvs server but it tell me thet the ssh 
>port was closed. Could you open it again? thanks.
This probably was a temporary failure of the whole machine. My c200 
keeps failing on my :-( I'm experiancing involuntary reboots all of 
the time. I'm sorry about this! The machine will be replaced as soon 
as I have some money. But for not it must do!

>By the way I had a little change in the Datasource object that would allow to 
>use any driver besides mysql and postgres without modifying the source code.
What other drivers are there? Is there anything you didn't tell us :-))

>On this direction I woud like to make orm definitions driver independent. I 
>mean no mather if you use mysql or postgres or any other a field definition 
>should no change. This implies to select a group of columns types and 
>simulate them where no available.
>
>This should no limit the program to use more than a driver any given moment. 
>So you could have two or more diferent Datasources connected to diferent 
>databases. 
Ok. Let me say first that I can see your point here. :-) Now here
comes mine: My idea with orm is, that it's as close to the RDBMS as it
can. That's why I decided to create a datatype/column class pair for
every datatype a specific backend provides. Datatypes that exist in
all backends (the basic float, integer and string types etc) are
defined in orm.columns and are the same classes for every backend. 
They also work with every backend right now.

There is a specific orm.adapters.*.columns module for each backend 
which (re-)defines Python classes for each type which is specific to 
a backend. This way orm can benefit from the specific features of an 
RDBMS but be minimalist, too.

I don't think simulation is wise: think of PostgreSQL's datatypes for
IPs and netmasks for instance. In MySQL you'd probably store these as
strings.  There's nothing wrong with that, people do this. On the
other hand PostgreSQL provides a specifc datatype and orm makes use of
this, as it should. In Python it will return an object which actually
represents an IP as an integer.

If a user wants to create a datatype/column pair specifically for 
MySQL to do the same thing he can. However, I don't think it's wise 
to do that inside orm: the task is just to special. If we'd emulate 
every type of every backend that's not supported in another backend 
we'd add quite some complexity to orm which I'd like to avoid. Also, 
even if we do, these type do not exist at SQL level so that orm's 
support is only half of the job anway.

Some differences are very subtle: MySQL's NUMERIC type fits into
Python's integer type nicely. For PostgreSQL's NUMERIC type I had to
write a custom datatype/column pair which uses an external module
called Fixedpoint. Fixedpoint does arbitrary precision math, as pgsql
does.

>Ok, this implies other things too. I a object is related to a Datasource what 
>should happen when is associated to another different? How a copy should 
>work? or a migration?
For copying and migration you will need two datamodels. This is mostly 
due to the fact that MySQL and PostgreSQL use different mechanisms to 
return new AUTO INCREMENT values. Here's an example of converting a domain/
host database from MySQL to PostgreSQL:

# my_beans.py
from orm.columns import *                
from orm.adapters.mysql.columns import *

class host(dbclass):
      columns = { "id": autoincrement(),
                  "name": varchar(),
                  "ip": varchar() }

class domain(dbclass):
      columns = { "id": autoincrement(),
                  "name": varchar(),
                  "hosts": one2many(host) }


# pg_beans.py
from orm.columns import *                
from orm.adapters.pgsql.columns import * 

class host(dbclass):
      columns = { "id": serial(),
                  "name": varchar(),
                  "ip": inet() }

class domain(dbclass):
      columns = { "id": serial(),
                  "name": varchar(),
                  "hosts": one2many(host) }

# copy.py
import my_beans
import pg_beans

my_ds = ...
pg_ds = ...

for domain in my_ds.select(my_beans.domain):
    new_domain = pg_beans.domain(name=domain.name)
    pg_ds.insert(new_domain)

    for host in domain.hosts:
        new_host = pg_beans.host(name=host.name,
                                 ip=host.ip) # the inet class's
                                             # convert() takes strings, too
                                             # I think...
        pg_ds.insert(new_host)
        del new_host # delete the object from memory. This is needed 
                     # for some reason I didn't quite get.

    del new_domain

pg_ds.commit()



>Well, just ideas while I begin to finish my work.
I know that flexibility in terms of db backend would be nice. I
haven't considered it with orm to keep things simple. Also keep in
mind that orm is intended to coexist with hand-writen SQL. This does
not change nicely from one db to another, either. Supporting several
backends as JDBC does was not intended, really.

If you have any ideas on how to achive it easily I'd be eager to here
them.

>Regards to all.
Best wishes to you!

Diedrich
-- 
           _..._                            Diedrich Vorberg
         .'     '.
        /  _   _  \                         http://www.tux4web.de
        | (o)_(o) |                         info@tux4web.de
         \(     ) /            .---.
         //'._.'\ \           /     \       Internet Dienstleistungen
        //   .   \ \          \.@-@./       und 'Consulting'.
       ||   .     \ \         /`\_/`\
       |\   :     / |        //  _  \\      Linux Rules!
       \ `) '   (`  /_      | \     )|_
     _)``".____,.'"` (_    /`\_`>  <_/ \
     )     )'--'(     (    \__/'---'\__/
      '---`      `---`