I am thinking about moving from home grown data access classes, to
sqlalchemy for a simple ETL tool for moving from legacy databases - at
least for the Extract and simplest of Transformations.
Example of what I'm trying to achieve.. if I have a customer table in
the legacy database, and a new_customer table (I show two examples of
target databases) in the target system.
(source and target are currently Oracle)
create table old_customer (cunr number, cutype char(1));
insert into customer values (1,'A');
--create table new_1_customer(id number, type number);
--create table new_2_customer(cunr number, cutype number);
I want to use SA to provide a customer object containing both old and
new columns, with any required column level transformations.
e.g. in the first example, I want an object with the following
properties
customer.o_cunr
customer.o_cutype
customer.id
customer.type (converted from cutype through mapping function)
and in the second:
customer.o_cunr
customer.o_cutype
customer.cunr
customer.cutype (converted from cutype through mapping function)
eventually I want to provide these mapping separate from the main
class definition.. but I start with them inline:
from sqlalchemy import *
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine=create_engine('oracle://gw_val:[EMAIL PROTECTED]')
Base = declarative_base(engine=engine)
class Customer(Base):
__tablename__ = 'old_customer'
__table_args__ = {'autoload':True}
__mapper_args__ = {'column_prefix' : 'o_'}
id = Column('cunr', Integer, primary_key=True)
def _get_cutype(self):
# Trival mapping
def mapper(old_type):
return ord(old_type)
return mapper(self.o_cutype)
type = property(_get_cutype)
Session = sessionmaker()
session = Session()
customer = session.query(Customer).filter_by(id=1).one()
print customer.id
print 'type mapping %s -> %d' % (customer.o_cutype, customer.type)
Which works fine.
However, I can't use the same construct for the second example (where
the columns have the same names)
from sqlalchemy import *
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine=create_engine('oracle://gw_val:[EMAIL PROTECTED]')
Base = declarative_base(engine=engine)
class Customer(Base):
__tablename__ = 'old_customer'
__table_args__ = {'autoload':True}
__mapper_args__ = {'column_prefix' : 'o_'}
o_cunr = Column('cunr', Integer, primary_key=True)
def _get_cutype(self):
# Trival mapping
def mapper(old_type):
return ord(old_type)
return mapper(self.o_cutype)
cutype = property(_get_cutype)
Session = sessionmaker()
session = Session()
customer = session.query(Customer).filter_by(o_cunr=1).one()
print customer.o_cunr
print 'type mapping %s -> %d' % (customer.o_cutype, customer.cutype)
Gives me:
Traceback (most recent call last):
File "./test2.py", line 33, in <module>
print 'type mapping %s -> %d' % (customer.o_cutype,
customer.cutype)
AttributeError: 'Customer' object has no attribute 'o_cutype'
Any suggestions on the best way to code this so I don't overwrite the
prefixed columns if they happen to have the same name in legacy and
target schemas, also with a long term goal of taking the explicit
mapping code out of each class writing something more like this:
class Customer(MyBase):
__tablename__ = 'old_customer'
__table_args__ = {'autoload':True}
__column_mappings__ = {
('cunr', 'id', None),
('cutype', 'type', lambda x : ord(x))
}
Thanks
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---