[Sqlalchemy-commits] [1418] sqlalchemy/branches/schema/lib/sqlalchemy: polymorph tweaks
Brought to you by:
zzzeek
From: <co...@sq...> - 2006-05-06 18:52:16
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><style type="text/css"><!-- #msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } #msg dt { float: left; width: 6em; font-weight: bold; } #msg dt:after { content:':';} #msg dl, #msg dt, #msg ul, #msg li { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } #msg dl a { font-weight: bold} #msg dl a:link { color:#fc3; } #msg dl a:active { color:#ff0; } #msg dl a:visited { color:#cc6; } h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; } #msg ul, pre { overflow: auto; } #patch { width: 100%; } #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;} #patch .propset h4, #patch .binary h4 {margin:0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;} #patch .propset .diff, #patch .binary .diff {padding:10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, .info {color:#888;background:#fff;} --></style> <title>[1418] sqlalchemy/branches/schema/lib/sqlalchemy: polymorph tweaks</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1418</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-05-06 13:52:03 -0500 (Sat, 06 May 2006)</dd> </dl> <h3>Log Message</h3> <pre>polymorph tweaks</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemybranchesschemaexamplespolymorphpolymorphpy">sqlalchemy/branches/schema/examples/polymorph/polymorph.py</a></li> <li><a href="#sqlalchemybranchesschemaexamplespolymorphsinglepy">sqlalchemy/branches/schema/examples/polymorph/single.py</a></li> <li><a href="#sqlalchemybranchesschemalibsqlalchemyormpropertiespy">sqlalchemy/branches/schema/lib/sqlalchemy/orm/properties.py</a></li> <li><a href="#sqlalchemybranchesschemalibsqlalchemyschemapy">sqlalchemy/branches/schema/lib/sqlalchemy/schema.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemybranchesschemaexamplespolymorphpolymorphpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/examples/polymorph/polymorph.py (1417 => 1418)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/examples/polymorph/polymorph.py 2006-05-06 18:28:48 UTC (rev 1417) +++ sqlalchemy/branches/schema/examples/polymorph/polymorph.py 2006-05-06 18:52:03 UTC (rev 1418) </span><span class="lines">@@ -4,35 +4,36 @@ </span><span class="cx"> # this example illustrates a polymorphic load of two classes, where each class has a very </span><span class="cx"> # different set of properties </span><span class="cx"> </span><del>-db = create_engine('sqlite://', echo='debug', echo_uow=False) </del><ins>+metadata = BoundMetaData('sqlite://', echo='debug') </ins><span class="cx"> </span><span class="cx"> # a table to store companies </span><del>-companies = Table('companies', db, </del><ins>+companies = Table('companies', metadata, </ins><span class="cx"> Column('company_id', Integer, primary_key=True), </span><del>- Column('name', String(50))).create() </del><ins>+ Column('name', String(50))) </ins><span class="cx"> </span><span class="cx"> # we will define an inheritance relationship between the table "people" and "engineers", </span><span class="cx"> # and a second inheritance relationship between the table "people" and "managers" </span><del>-people = Table('people', db, </del><ins>+people = Table('people', metadata, </ins><span class="cx"> Column('person_id', Integer, primary_key=True), </span><span class="cx"> Column('company_id', Integer, ForeignKey('companies.company_id')), </span><span class="cx"> Column('name', String(50)), </span><del>- Column('type', String(30))).create() </del><ins>+ Column('type', String(30))) </ins><span class="cx"> </span><del>-engineers = Table('engineers', db, </del><ins>+engineers = Table('engineers', metadata, </ins><span class="cx"> Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True), </span><span class="cx"> Column('status', String(30)), </span><span class="cx"> Column('engineer_name', String(50)), </span><span class="cx"> Column('primary_language', String(50)), </span><del>- ).create() </del><ins>+ ) </ins><span class="cx"> </span><del>-managers = Table('managers', db, </del><ins>+managers = Table('managers', metadata, </ins><span class="cx"> Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True), </span><span class="cx"> Column('status', String(30)), </span><span class="cx"> Column('manager_name', String(50)) </span><del>- ).create() </del><ins>+ ) + +metadata.create_all() </ins><span class="cx"> </span><del>- </del><span class="cx"> # create our classes. The Engineer and Manager classes extend from Person. </span><span class="cx"> class Person(object): </span><span class="cx"> def __init__(self, **kwargs): </span><span class="lines">@@ -54,8 +55,7 @@ </span><span class="cx"> return "Company %s" % self.name </span><span class="cx"> </span><span class="cx"> </span><del>-# create a union that represents both types of joins. we have to use -# nulls to pad out the disparate columns. </del><ins>+# create a union that represents both types of joins. </ins><span class="cx"> person_join = polymorphic_union( </span><span class="cx"> { </span><span class="cx"> 'engineer':people.join(engineers), </span><span class="lines">@@ -68,7 +68,7 @@ </span><span class="cx"> mapper(Manager, managers, inherits=person_mapper, polymorphic_identity='manager') </span><span class="cx"> </span><span class="cx"> mapper(Company, companies, properties={ </span><del>- 'employees': relation(Person, lazy=True, private=True, backref='company') </del><ins>+ 'employees': relation(Person, lazy=False, private=True, backref='company') </ins><span class="cx"> }) </span><span class="cx"> </span><span class="cx"> session = create_session() </span><span class="lines">@@ -105,7 +105,4 @@ </span><span class="cx"> session.delete(c) </span><span class="cx"> session.flush() </span><span class="cx"> </span><del>-managers.drop() -engineers.drop() -people.drop() -companies.drop() </del><ins>+metadata.drop_all() </ins></span></pre></div> <a id="sqlalchemybranchesschemaexamplespolymorphsinglepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/examples/polymorph/single.py (1417 => 1418)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/examples/polymorph/single.py 2006-05-06 18:28:48 UTC (rev 1417) +++ sqlalchemy/branches/schema/examples/polymorph/single.py 2006-05-06 18:52:03 UTC (rev 1418) </span><span class="lines">@@ -1,25 +1,85 @@ </span><span class="cx"> from sqlalchemy import * </span><span class="cx"> </span><del>-metadata = MetaData() </del><ins>+metadata = BoundMetaData('sqlite://', echo='debug') </ins><span class="cx"> </span><ins>+# a table to store companies +companies = Table('companies', metadata, + Column('company_id', Integer, primary_key=True), + Column('name', String(50))) + </ins><span class="cx"> employees_table = Table('employees', metadata, </span><span class="cx"> Column('employee_id', Integer, primary_key=True), </span><ins>+ Column('company_id', Integer, ForeignKey('companies.company_id')), </ins><span class="cx"> Column('name', String(50)), </span><del>- Column('type', String(20)) </del><ins>+ Column('type', String(20)), + Column('engineer_name', String(50)), + Column('primary_language', String(50)), + Column('manager_name', String(50)) </ins><span class="cx"> ) </span><span class="cx"> </span><del>-engine = create_engine('sqlite:///') -metadata.create_all(engine) </del><ins>+metadata.create_all() </ins><span class="cx"> </span><del>-class Employee(object): - pass - -class Manager(Employee): - pass - -class Engineer(Employee): - pass </del><ins>+class Person(object): + def __init__(self, **kwargs): + for key, value in kwargs.iteritems(): + setattr(self, key, value) + def __repr__(self): + return "Ordinary person %s" % self.name +class Engineer(Person): + def __repr__(self): + return "Engineer %s, status %s, engineer_name %s, primary_language %s" % (self.name, self.status, self.engineer_name, self.primary_language) +class Manager(Person): + def __repr__(self): + return "Manager %s, status %s, manager_name %s" % (self.name, self.status, self.manager_name) +class Company(object): + def __init__(self, **kwargs): + for key, value in kwargs.iteritems(): + setattr(self, key, value) + def __repr__(self): + return "Company %s" % self.name </ins><span class="cx"> </span><del>-employee_mapper = mapper(Employee, employees_table, polymorphic_on=employees_table.c.type) </del><ins>+person_mapper = mapper(Person, employees_table, polymorphic_on=employees_table.c.type, polymorphic_identity='person') </ins><span class="cx"> manager_mapper = mapper(Manager, inherits=employee_mapper, polymorphic_identity='manager') </span><span class="cx"> engineer_mapper = mapper(Engineer, inherits=employee_mapper, polymorphic_identity='engineer') </span><ins>+ + + +mapper(Company, companies, properties={ + 'employees': relation(Person, lazy=True, private=True, backref='company') +}) + +session = create_session() +c = Company(name='company1') +c.employees.append(Manager(name='pointy haired boss', status='AAB', manager_name='manager1')) +c.employees.append(Engineer(name='dilbert', status='BBA', engineer_name='engineer1', primary_language='java')) +c.employees.append(Person(name='joesmith', status='HHH')) +c.employees.append(Engineer(name='wally', status='CGG', engineer_name='engineer2', primary_language='python')) +c.employees.append(Manager(name='jsmith', status='ABA', manager_name='manager2')) +session.save(c) +session.flush() + +session.clear() + +c = session.query(Company).get(1) +for e in c.employees: + print e, e._instance_key, e.company + +print "\n" + +dilbert = session.query(Person).get_by(name='dilbert') +dilbert2 = session.query(Engineer).get_by(name='dilbert') +assert dilbert is dilbert2 + +dilbert.engineer_name = 'hes dibert!' + +session.flush() +session.clear() + +c = session.query(Company).get(1) +for e in c.employees: + print e, e._instance_key + +session.delete(c) +session.flush() + +metadata.drop_all() </ins></span></pre></div> <a id="sqlalchemybranchesschemalibsqlalchemyormpropertiespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/lib/sqlalchemy/orm/properties.py (1417 => 1418)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/lib/sqlalchemy/orm/properties.py 2006-05-06 18:28:48 UTC (rev 1417) +++ sqlalchemy/branches/schema/lib/sqlalchemy/orm/properties.py 2006-05-06 18:52:03 UTC (rev 1418) </span><span class="lines">@@ -584,18 +584,18 @@ </span><span class="cx"> </span><span class="cx"> if not self.uselist: </span><span class="cx"> if isnew: </span><del>- h.setattr_clean(self._instance(session, row, imap)) </del><ins>+ h.setattr_clean(self.mapper._instance(session, decorated_row, imap, None)) </ins><span class="cx"> else: </span><span class="cx"> # call _instance on the row, even though the object has been created, </span><span class="cx"> # so that we further descend into properties </span><del>- self._instance(session, row, imap) </del><ins>+ self.mapper._instance(session, decorated_row, imap, None) </ins><span class="cx"> </span><span class="cx"> return </span><span class="cx"> elif isnew: </span><span class="cx"> result_list = h </span><span class="cx"> else: </span><span class="cx"> result_list = getattr(instance, self.key) </span><del>- self._instance(session, row, imap, result_list) </del><ins>+ self.mapper._instance(session, decorated_row, imap, result_list) </ins><span class="cx"> </span><span class="cx"> def _create_decorator_row(self): </span><span class="cx"> class DecoratorDict(object): </span><span class="lines">@@ -629,10 +629,6 @@ </span><span class="cx"> self._create_eager_chain() </span><span class="cx"> return self._row_decorator(row) </span><span class="cx"> </span><del>- def _instance(self, session, row, imap, result_list=None): - """gets an instance from a row, via this EagerLoader's mapper.""" - return self.mapper._instance(session, self._decorate_row(row), imap, result_list) - </del><span class="cx"> class GenericOption(mapper.MapperOption): </span><span class="cx"> """a mapper option that can handle dotted property names, </span><span class="cx"> descending down through the relations of a mapper until it </span></span></pre></div> <a id="sqlalchemybranchesschemalibsqlalchemyschemapy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/lib/sqlalchemy/schema.py (1417 => 1418)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/lib/sqlalchemy/schema.py 2006-05-06 18:28:48 UTC (rev 1417) +++ sqlalchemy/branches/schema/lib/sqlalchemy/schema.py 2006-05-06 18:52:03 UTC (rev 1418) </span><span class="lines">@@ -15,6 +15,7 @@ </span><span class="cx"> </span><span class="cx"> """ </span><span class="cx"> from sqlalchemy import sql, types, exceptions,util </span><ins>+import sqlalchemy </ins><span class="cx"> import copy, re, string </span><span class="cx"> </span><span class="cx"> __all__ = ['SchemaItem', 'Table', 'Column', 'ForeignKey', 'Sequence', 'Index', </span></span></pre> </div> </div> </body> </html> |