On Fri, 5 Dec 2008, Faheem Mitha wrote:

>
> Hi,
>
> I'm using sqla with the following schema (see below). I'm creating a cell 
> object implicitly, using the function make_cell and the association proxy 
> pattern.
>
> def make_cell(patient_obj, snp_obj, snpval):
>    patient_obj.snps[snp_obj] = snpval
>    return patient_obj
>
> My question is, is there some way to get my hands on the Cell object that was 
> just created? If possible, I'd like make_cell to return the cell object. My 
> immediate reason is that this would make it easy to save the object using 
> session.save() (there might be some indirect way to do this, of course), but 
> it would be nice anyway.

A followup to my original post. I must be doing something wrong, because 
the Cell object is not being saved. and the proxy in the "other direction" 
is not being updated either. I'm reluctant to ask for debugging help, but 
I'm having difficulty tracking down the problem.

The files included in order below are

Schema file: dbschema.py 
Utility functions: dbutils.py
Session file: dbsession.py

The last file runs the actual code to populate the dbs, and is one big 
function, make_tables.

The most relevant lines here are:

print "p1.snps is %s"%p1.snps
print "s.patients is %s"%s.patients
print "cell table is %s"%list(cell_table.select().execute())
[...]
get_obj(session, Cell)

The output I'm getting is

p1.snps is {<SNP rs10458597>: <Snpval 0>}
s.patients is {}
cell table is []
[...]
*** list of Cell objects in class. ***
*** end list of Cell objects. ***

I wouldn't expect the last three, namely s.patients, cell table and
list of Cell objects to all be empty. Can someone tell me what I'm
doing wrong? For an experienced person, it may be obvious.

Note: My use of cascade in the Mappers may be redundant. I just put it
in there for good measure, and I'm not sure what it does.

                                                     Regards, Faheem.

****************************************************************************
dbschema.py
****************************************************************************
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
from datetime import datetime

metadata = MetaData('sqlite:///btsnp.sqlite')

patient_table = Table(
     'patient', metadata,
     Column('id', String(20), primary_key=True, index=True),
     Column('celfilename', String(30), nullable=False, index=True, unique=True),
     Column('sex', String(1)),
     )

cell_table = Table(
     'cell', metadata,
     Column('patient_id',  None, ForeignKey('patient.id', onupdate='CASCADE', 
ondelete='CASCADE'), index=True, nullable=False, primary_key=True),
     Column('snp_id',  None, ForeignKey('snp.rsid', onupdate='CASCADE', 
ondelete='CASCADE'),  index=True, nullable=False, primary_key=True),
     Column('snpval_id',  None, ForeignKey('snpval.val', onupdate='CASCADE', 
ondelete='CASCADE'), index=True, nullable=False)
     )

snp_table = Table(
     'snp', metadata,
     Column('rsid', String(20), nullable=False, primary_key=True),
     Column('chromosome', Integer, nullable=False),
     Column('location', Integer, nullable=False),
     Column('probe_set_id', String(20), nullable=False, unique=True),
     Column('allele', String(3), nullable=False),
     )

snpval_table = Table(
     'snpval', metadata,
     Column('val', Integer, primary_key=True),
     )

metadata.create_all()

def create_cell(snp, snpval):
     return Cell(snp=snp, snpval=snpval)

class Patient(object):
     def __init__(self, id, celfilename, sex):
         self.id = id
         self.celfilename = celfilename
         self.sex = sex
     def __repr__(self):
         return '<Patient %s>'%self.id
     snps = association_proxy('by_rsid', 'snpval', creator=create_cell)

class Cell(object):
     def __init__(self, patient=None, snp=None, snpval=None):
         self.patient = patient
         self.snp = snp
         self.snpval = snpval
     def __repr__(self):
         return '<Cell %s>'%self.snpval

class Snp(object):
     def __init__(self, rsid, chromosome, location, probe_set_id, allele):
         self.rsid = rsid
         self.chromosome = chromosome
         self.location = location
         self.probe_set_id = probe_set_id
         self.allele = allele
     def __repr__(self):
         return '<SNP %s>'%self.rsid
     patients = association_proxy('by_patient', 'snpval', creator=create_cell)

class Snpval(object):
     def __init__(self, val):
         self.val = val
     def __repr__(self):
         return '<Snpval %s>'%self.val

# 'cells' corresponds to a 1 to many relation.
mapper(Patient, patient_table, properties={'cells':relation(Cell, 
backref='patient'),
                                            'by_rsid': relation(Cell, cascade = 
"all, delete-orphan", collection_class=attribute_mapped_collection('snp'))}
                                            )
# 'patient_snpval' corresponds to a many to 1 relation.
# 'patient_snpval' corresponds to a 1 to 1 relation.
mapper(Cell, cell_table, properties={'snp':relation(Snp, backref='cells'),
                                      'snpval':cell_table.c.snpval_id,
                                      'snpval_obj':relation(Snpval, 
uselist=False, backref='cell'),
                                      })
mapper(Snp, snp_table, properties={'by_patient': relation(Cell, cascade = "all, 
delete-orphan", collection_class=attribute_mapped_collection('patient'))})
mapper(Snpval, snpval_table)

****************************************************************************
dbutils.py
****************************************************************************
def add_obj(session, obj):
     """ Check if object primary key exists in db. If so,exit, else
     add.
     """
     from sqlalchemy import and_
     from sqlalchemy.orm import object_mapper
     mapper = object_mapper(obj)
     pid = mapper.primary_key_from_instance(obj)
     criterion = and_(*(col == val for col, val in zip(mapper.primary_key, 
mapper.primary_key_from_instance(obj))))
     if session.query(obj.__class__).filter(criterion).count() > 0:
         print "%s object with id %s is already in db."%(type(obj).__name__, 
pid)
         exit
     else:
         session.save(obj)
         session.commit()

def make_cell(patient_obj, snp_obj, snpval):
     print "making cell..."
     patient_obj.snps[snp_obj] = snpval
     return patient_obj

def get_obj(session, cls):
     query = session.query(cls)
     print "*** list of %s objects in class. ***"%cls.__name__
     for obj in query:
         print "%s is %s"%(cls.__name__, obj)
     print "*** end list of %s objects. ***"%cls.__name__

************************************************************************
dbsession.py
************************************************************************

def make_tables():
     from dbschema import cell_table, patient_table, Patient, Cell, Snp, 
Snpval, metadata
     from sqlalchemy import *
     from sqlalchemy.orm import *
     from dbutils import add_obj, get_obj, make_cell

     import logging
     logging.basicConfig()
     logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
     logging.getLogger('sqlalchemy.orm.unitofwork').setLevel(logging.DEBUG)
     metadata.bind.echo = True

     Session = sessionmaker()
     session = Session()

     patientname1 = "John"
     patientname2 = "Ted"
     cfname1 = "DUKE00001_plateA_A10.CEL"
     cfname2 = "DUKE00001_plateA_A11.CEL"
     sex = "M"

     rsid = "rs10458597"
     chromosome = "1"
     location = "554484"
     snpval = "AA"
     psid1 = "SNP_A-1780419"
     allele = "A/G"

     p1 = Patient(patientname1, cfname1, sex)
     p2 = Patient(patientname2, cfname2, sex)
     s = Snp(rsid, chromosome, location, psid1, allele)
     svlst = []
     for i in [0, 1, 2]:
         svlst.append(Snpval(i))
     make_cell(p1, s, svlst[0])
     make_cell(p2, s, svlst[1])
     print "p1.snps is %s"%p1.snps
     print "s.patients is %s"%s.patients
     print "cell table is %s"%list(cell_table.select().execute())

     for i in [0, 1, 2]:
         add_obj(session, svlst[i])
     add_obj(session, p1)
     add_obj(session, p2)
     add_obj(session, s)

     ## Delete all patient objects.
     #session.query(Patient).delete()

     session.flush()
     get_obj(session, Patient)
     get_obj(session, Snp)
     get_obj(session, Snpval)
     get_obj(session, Cell)

make_tables()

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to