sqlalchemy-commits Mailing List for SQLAlchemy (Page 373)
Brought to you by:
zzzeek
You can subscribe to this list here.
2006 |
Jan
|
Feb
(74) |
Mar
(167) |
Apr
(127) |
May
(190) |
Jun
(119) |
Jul
(77) |
Aug
(82) |
Sep
(84) |
Oct
(153) |
Nov
(45) |
Dec
(54) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(109) |
Feb
(80) |
Mar
(110) |
Apr
(106) |
May
(92) |
Jun
(147) |
Jul
(288) |
Aug
(307) |
Sep
(108) |
Oct
(156) |
Nov
(147) |
Dec
(134) |
2008 |
Jan
(126) |
Feb
(91) |
Mar
(184) |
Apr
(208) |
May
(212) |
Jun
(54) |
Jul
(106) |
Aug
(80) |
Sep
(58) |
Oct
(80) |
Nov
(119) |
Dec
(220) |
2009 |
Jan
(202) |
Feb
(50) |
Mar
(70) |
Apr
(46) |
May
(80) |
Jun
(61) |
Jul
(146) |
Aug
(81) |
Sep
(71) |
Oct
(74) |
Nov
(66) |
Dec
(82) |
2010 |
Jan
(112) |
Feb
(169) |
Mar
(235) |
Apr
(77) |
May
(22) |
Jun
(31) |
Jul
(46) |
Aug
(46) |
Sep
(70) |
Oct
(36) |
Nov
(37) |
Dec
(79) |
2011 |
Jan
(46) |
Feb
(54) |
Mar
(65) |
Apr
(73) |
May
(31) |
Jun
(46) |
Jul
(40) |
Aug
(36) |
Sep
(44) |
Oct
(33) |
Nov
(19) |
Dec
(10) |
2012 |
Jan
(60) |
Feb
(37) |
Mar
(35) |
Apr
(28) |
May
(27) |
Jun
(50) |
Jul
(33) |
Aug
(88) |
Sep
(64) |
Oct
(74) |
Nov
(62) |
Dec
(41) |
2013 |
Jan
(30) |
Feb
(37) |
Mar
(39) |
Apr
(52) |
May
(40) |
Jun
(85) |
Jul
(74) |
Aug
(76) |
Sep
(26) |
Oct
(76) |
Nov
(63) |
Dec
(65) |
2014 |
Jan
(68) |
Feb
(82) |
Mar
(87) |
Apr
(24) |
May
(66) |
Jun
(34) |
Jul
(86) |
Aug
(75) |
Sep
(70) |
Oct
(41) |
Nov
(23) |
Dec
(53) |
2015 |
Jan
(40) |
Feb
(39) |
Mar
(69) |
Apr
(64) |
May
(40) |
Jun
(43) |
Jul
(20) |
Aug
(48) |
Sep
(38) |
Oct
(28) |
Nov
(34) |
Dec
(44) |
2016 |
Jan
(82) |
Feb
(49) |
Mar
(25) |
Apr
(21) |
May
(19) |
Jun
(46) |
Jul
(38) |
Aug
(21) |
Sep
(33) |
Oct
(44) |
Nov
(26) |
Dec
(10) |
2017 |
Jan
(52) |
Feb
(18) |
Mar
(61) |
Apr
(43) |
May
(57) |
Jun
(36) |
Jul
(37) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
<!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>[1132] sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py: tweak to get_direction, rolls back a comparison of "foreigntable" to "parent"/"mapper" table to be more constrained.</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1132</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-12 20:39:52 -0600 (Sun, 12 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>tweak to get_direction, rolls back a comparison of "foreigntable" to "parent"/"mapper" table to be more constrained. this change was originally in [changeset:1101] to help out the polymorph example but it now works without it. the change breaks the Post/Comment relationship in the ZBlog demo since the Post mapper has the comments table inside of it (also with no workaround).</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemymappingpropertiespy">sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemymappingpropertiespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py (1131 => 1132)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-13 02:04:13 UTC (rev 1131) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-13 02:39:52 UTC (rev 1132) </span><span class="lines">@@ -228,9 +228,11 @@ </span><span class="cx"> return PropertyLoader.ONETOMANY </span><span class="cx"> elif self.secondaryjoin is not None: </span><span class="cx"> return PropertyLoader.MANYTOMANY </span><del>- elif self.foreigntable is self.target or self.foreigntable in self.mapper.tables: </del><ins>+ elif self.foreigntable == self.target: + #elif self.foreigntable is self.target or self.foreigntable in self.mapper.tables: </ins><span class="cx"> return PropertyLoader.ONETOMANY </span><del>- elif self.foreigntable is self.parent.table or self.foreigntable in self.parent.tables: </del><ins>+ elif self.foreigntable == self.parent.table: + #elif self.foreigntable is self.parent.table or self.foreigntable in self.parent.tables: </ins><span class="cx"> return PropertyLoader.MANYTOONE </span><span class="cx"> else: </span><span class="cx"> raise ArgumentError("Cant determine relation direction") </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-13 02:04:21
|
<!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>[1131] sqlalchemy/trunk/CHANGES: caveat</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1131</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-12 20:04:13 -0600 (Sun, 12 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>caveat</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunkCHANGES">sqlalchemy/trunk/CHANGES</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunkCHANGES"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/CHANGES (1130 => 1131)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/CHANGES 2006-03-13 02:00:21 UTC (rev 1130) +++ sqlalchemy/trunk/CHANGES 2006-03-13 02:04:13 UTC (rev 1131) </span><span class="lines">@@ -9,7 +9,8 @@ </span><span class="cx"> this can be overridden by using custom primary/secondary joins. </span><span class="cx"> - added onupdate parameter to Column, will exec SQL/python upon an update </span><span class="cx"> statement.Also adds "for_update=True" to all DefaultGenerator subclasses </span><del>-- added rudimentary support for Oracle table reflection. </del><ins>+- added user-contributed support for Oracle table reflection; still +some bugs to work out regarding composite primary keys/dictionary selection </ins><span class="cx"> - checked in an initial Firebird module, awaiting testing. </span><span class="cx"> - added sql.ClauseParameters dictionary object as the result for </span><span class="cx"> compiled.get_params(), does late-typeprocessing of bind parameters so </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-13 02:00:32
|
<!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>[1130] sqlalchemy/trunk/test: oracle is requiring dictionary params to be in a clean dict, added conversion</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1130</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-12 20:00:21 -0600 (Sun, 12 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>oracle is requiring dictionary params to be in a clean dict, added conversion some fixes to unit tests</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemyenginepy">sqlalchemy/trunk/lib/sqlalchemy/engine.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemyexceptionspy">sqlalchemy/trunk/lib/sqlalchemy/exceptions.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemysqlpy">sqlalchemy/trunk/lib/sqlalchemy/sql.py</a></li> <li><a href="#sqlalchemytrunktestobjectstorepy">sqlalchemy/trunk/test/objectstore.py</a></li> <li><a href="#sqlalchemytrunktesttesttypespy">sqlalchemy/trunk/test/testtypes.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemyenginepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/engine.py (1129 => 1130)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/engine.py 2006-03-13 01:13:47 UTC (rev 1129) +++ sqlalchemy/trunk/lib/sqlalchemy/engine.py 2006-03-13 02:00:21 UTC (rev 1130) </span><span class="lines">@@ -586,14 +586,7 @@ </span><span class="cx"> if statement is None: </span><span class="cx"> return cursor </span><span class="cx"> </span><del>- executemany = parameters is not None and isinstance(parameters, list) - - if self.positional: - if executemany: - parameters = [p.values() for p in parameters] - else: - parameters = parameters.values() - </del><ins>+ parameters = self._convert_compiled_params(parameters) </ins><span class="cx"> self.execute(statement, parameters, connection=connection, cursor=cursor, return_raw=True) </span><span class="cx"> return cursor </span><span class="cx"> </span><span class="lines">@@ -657,12 +650,12 @@ </span><span class="cx"> return ResultProxy(cursor, self, typemap=typemap) </span><span class="cx"> </span><span class="cx"> def _execute(self, c, statement, parameters): </span><ins>+ if parameters is None: + if self.positional: + parameters = () + else: + parameters = {} </ins><span class="cx"> try: </span><del>- if parameters is None: - if self.positional: - parameters = () - else: - parameters = {} </del><span class="cx"> c.execute(statement, parameters) </span><span class="cx"> except Exception, e: </span><span class="cx"> raise exceptions.SQLError(statement, parameters, e) </span><span class="lines">@@ -671,15 +664,26 @@ </span><span class="cx"> c.executemany(statement, parameters) </span><span class="cx"> self.context.rowcount = c.rowcount </span><span class="cx"> </span><del>- def proxy(self, statement=None, parameters=None): </del><ins>+ def _convert_compiled_params(self, parameters): </ins><span class="cx"> executemany = parameters is not None and isinstance(parameters, list) </span><ins>+ # the bind params are a CompiledParams object. but all the DBAPI's hate + # that object (or similar). so convert it to a clean + # dictionary/list/tuple of dictionary/tuple of list + if parameters is not None: + if self.positional: + if executemany: + parameters = [p.values() for p in parameters] + else: + parameters = parameters.values() + else: + if executemany: + parameters = [p.get_raw_dict() for p in parameters] + else: + parameters = parameters.get_raw_dict() + return parameters </ins><span class="cx"> </span><del>- if self.positional: - if executemany: - parameters = [p.values() for p in parameters] - else: - parameters = parameters.values() - </del><ins>+ def proxy(self, statement=None, parameters=None): + parameters = self._convert_compiled_params(parameters) </ins><span class="cx"> return self.execute(statement, parameters) </span><span class="cx"> </span><span class="cx"> def log(self, msg): </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemyexceptionspy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/exceptions.py (1129 => 1130)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/exceptions.py 2006-03-13 01:13:47 UTC (rev 1129) +++ sqlalchemy/trunk/lib/sqlalchemy/exceptions.py 2006-03-13 02:00:21 UTC (rev 1130) </span><span class="lines">@@ -17,6 +17,8 @@ </span><span class="cx"> self.statement = statement </span><span class="cx"> self.params = params </span><span class="cx"> self.orig = orig </span><ins>+ def __str__(self): + return SQLAlchemyError.__str__(self) + " " + repr(self.statement) + " " + repr(self.params) </ins><span class="cx"> </span><span class="cx"> class ArgumentError(SQLAlchemyError): </span><span class="cx"> """raised for all those conditions where invalid arguments are sent to constructed </span><span class="lines">@@ -38,4 +40,4 @@ </span><span class="cx"> </span><span class="cx"> class DBAPIError(SQLAlchemyError): </span><span class="cx"> """something weird happened with a particular DBAPI version""" </span><del>- pass </del><span class="cx">\ No newline at end of file </span><ins>+ pass </ins></span></pre></div> <a id="sqlalchemytrunklibsqlalchemysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/sql.py (1129 => 1130)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-13 01:13:47 UTC (rev 1129) +++ sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-13 02:00:21 UTC (rev 1130) </span><span class="lines">@@ -252,6 +252,11 @@ </span><span class="cx"> return [self[key] for key in self] </span><span class="cx"> def get_original_dict(self): </span><span class="cx"> return self.copy() </span><ins>+ def get_raw_dict(self): + d = {} + for k in self: + d[k] = self[k] + return d </ins><span class="cx"> </span><span class="cx"> class ClauseVisitor(object): </span><span class="cx"> """Defines the visiting of ClauseElements.""" </span></span></pre></div> <a id="sqlalchemytrunktestobjectstorepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/objectstore.py (1129 => 1130)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/objectstore.py 2006-03-13 01:13:47 UTC (rev 1129) +++ sqlalchemy/trunk/test/objectstore.py 2006-03-13 02:00:21 UTC (rev 1130) </span><span class="lines">@@ -144,7 +144,7 @@ </span><span class="cx"> class UnicodeTest(AssertMixin): </span><span class="cx"> def setUpAll(self): </span><span class="cx"> global uni_table </span><del>- uni_table = Table('test', db, </del><ins>+ uni_table = Table('uni_test', db, </ins><span class="cx"> Column('id', Integer, primary_key=True), </span><span class="cx"> Column('txt', Unicode(50))).create() </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemytrunktesttesttypespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/testtypes.py (1129 => 1130)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/testtypes.py 2006-03-13 01:13:47 UTC (rev 1129) +++ sqlalchemy/trunk/test/testtypes.py 2006-03-13 02:00:21 UTC (rev 1130) </span><span class="lines">@@ -96,7 +96,7 @@ </span><span class="cx"> def setUpAll(self): </span><span class="cx"> global unicode_table </span><span class="cx"> unicode_table = Table('unicode_table', db, </span><del>- Column('id', Integer, primary_key=True), </del><ins>+ Column('id', Integer, Sequence('uni_id_seq', optional=True), primary_key=True), </ins><span class="cx"> Column('unicode_data', Unicode(250)), </span><span class="cx"> Column('plain_data', String(250)) </span><span class="cx"> ) </span></span></pre> </div> </div> </body> </html> |
<!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>[1129] sqlalchemy/trunk/test: small tweak to select in order to fix [ticket:112]...the exported columns when doing select on a select() will be the column names, not the keys.</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1129</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-12 19:13:47 -0600 (Sun, 12 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>small tweak to select in order to fix [ticket:112]...the exported columns when doing select on a select() will be the column names, not the keys. this is with selects that have use_labels=False. which makes sense since using the "key" and not the name implies a label has to be used.</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemysqlpy">sqlalchemy/trunk/lib/sqlalchemy/sql.py</a></li> <li><a href="#sqlalchemytrunktestquerypy">sqlalchemy/trunk/test/query.py</a></li> <li><a href="#sqlalchemytrunktestselectpy">sqlalchemy/trunk/test/select.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/sql.py (1128 => 1129)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-13 01:06:33 UTC (rev 1128) +++ sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-13 01:13:47 UTC (rev 1129) </span><span class="lines">@@ -1272,7 +1272,7 @@ </span><span class="cx"> if self.use_labels: </span><span class="cx"> return column._make_proxy(self, name=column._label) </span><span class="cx"> else: </span><del>- return column._make_proxy(self, name=column.key) </del><ins>+ return column._make_proxy(self, name=column.name) </ins><span class="cx"> </span><span class="cx"> def append_whereclause(self, whereclause): </span><span class="cx"> self._append_condition('whereclause', whereclause) </span></span></pre></div> <a id="sqlalchemytrunktestquerypy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/query.py (1128 => 1129)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/query.py 2006-03-13 01:06:33 UTC (rev 1128) +++ sqlalchemy/trunk/test/query.py 2006-03-13 01:13:47 UTC (rev 1129) </span><span class="lines">@@ -124,7 +124,8 @@ </span><span class="cx"> self.assert_(r==[(3, 'ed'), (4, 'wendy'), (5, 'laura')]) </span><span class="cx"> r = self.users.select(offset=5, order_by=[self.users.c.user_id]).execute().fetchall() </span><span class="cx"> self.assert_(r==[(6, 'ralph'), (7, 'fido')]) </span><del>- </del><ins>+ + </ins><span class="cx"> def test_column_accessor(self): </span><span class="cx"> self.users.insert().execute(user_id=1, user_name='john') </span><span class="cx"> self.users.insert().execute(user_id=2, user_name='jack') </span></span></pre></div> <a id="sqlalchemytrunktestselectpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/select.py (1128 => 1129)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/select.py 2006-03-13 01:06:33 UTC (rev 1128) +++ sqlalchemy/trunk/test/select.py 2006-03-13 01:13:47 UTC (rev 1129) </span><span class="lines">@@ -174,6 +174,12 @@ </span><span class="cx"> select([table2.c.othername, func.count(table2.c.otherid)], group_by = [table2.c.othername]), </span><span class="cx"> "SELECT myothertable.othername, count(myothertable.otherid) FROM myothertable GROUP BY myothertable.othername" </span><span class="cx"> ) </span><ins>+ + def testoraclelimit(self): + e = create_engine('oracle') + users = Table('users', e, Column('name', String(10), key='username')) + self.runtest(select([users.c.username], limit=5), "SELECT name FROM (SELECT users.name AS name, ROW_NUMBER() OVER (ORDER BY users.rowid ASC) AS ora_rn FROM users) WHERE ora_rn<=5", engine=e) + </ins><span class="cx"> def testgroupby_and_orderby(self): </span><span class="cx"> self.runtest( </span><span class="cx"> select([table2.c.othername, func.count(table2.c.otherid)], group_by = [table2.c.othername], order_by = [table2.c.othername]), </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-13 01:06:44
|
<!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>[1128] sqlalchemy/trunk/test/defaults.py: tweak to mysql default test</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1128</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-12 19:06:33 -0600 (Sun, 12 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>tweak to mysql default test</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunktestdefaultspy">sqlalchemy/trunk/test/defaults.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunktestdefaultspy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/defaults.py (1127 => 1128)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/defaults.py 2006-03-13 00:24:54 UTC (rev 1127) +++ sqlalchemy/trunk/test/defaults.py 2006-03-13 01:06:33 UTC (rev 1128) </span><span class="lines">@@ -11,7 +11,7 @@ </span><span class="cx"> class DefaultTest(PersistTest): </span><span class="cx"> </span><span class="cx"> def setUpAll(self): </span><del>- global t, f, ts, currenttime </del><ins>+ global t, f, f2, ts, currenttime </ins><span class="cx"> x = {'x':50} </span><span class="cx"> def mydefault(): </span><span class="cx"> x['x'] += 1 </span><span class="lines">@@ -26,17 +26,20 @@ </span><span class="cx"> if is_oracle: </span><span class="cx"> ts = db.func.sysdate().scalar() </span><span class="cx"> f = select([func.count(1) + 5], engine=db).scalar() </span><ins>+ f2 = select([func.count(1) + 14], engine=db).scalar() </ins><span class="cx"> def1 = currenttime </span><span class="cx"> def2 = text("sysdate") </span><span class="cx"> deftype = Date </span><span class="cx"> elif use_function_defaults: </span><span class="cx"> f = select([func.count(1) + 5], engine=db).scalar() </span><ins>+ f2 = select([func.count(1) + 14], engine=db).scalar() </ins><span class="cx"> def1 = currenttime </span><span class="cx"> def2 = text("current_date") </span><span class="cx"> deftype = Date </span><span class="cx"> ts = db.func.current_date().scalar() </span><span class="cx"> else: </span><span class="cx"> f = select([func.count(1) + 5], engine=db).scalar() </span><ins>+ f2 = select([func.count(1) + 14], engine=db).scalar() </ins><span class="cx"> def1 = def2 = "3" </span><span class="cx"> ts = 3 </span><span class="cx"> deftype = Integer </span><span class="lines">@@ -74,7 +77,9 @@ </span><span class="cx"> z = t.c.col3.default.execute() </span><span class="cx"> self.assert_(50 <= x <= 57) </span><span class="cx"> self.assert_(y == 'imthedefault') </span><del>- self.assert_(z == 6) </del><ins>+ self.assert_(z == f) + # mysql/other db's return 0 or 1 for count(1) + self.assert_(5 <= z <= 6) </ins><span class="cx"> </span><span class="cx"> def testinsert(self): </span><span class="cx"> t.insert().execute() </span><span class="lines">@@ -95,7 +100,9 @@ </span><span class="cx"> self.echo("Currenttime "+ repr(ctexec)) </span><span class="cx"> l = t.select(t.c.col1==pk).execute() </span><span class="cx"> l = l.fetchone() </span><del>- self.assert_(l == (pk, 'im the update', 15, None, None, ctexec)) </del><ins>+ self.assert_(l == (pk, 'im the update', f2, None, None, ctexec)) + # mysql/other db's return 0 or 1 for count(1) + self.assert_(14 <= f2 <= 15) </ins><span class="cx"> </span><span class="cx"> class SequenceTest(PersistTest): </span><span class="cx"> </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-13 00:25:25
|
<!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>[1127] sqlalchemy/trunk: refactor to Compiled.get_params() to return new ClauseParameters object, a more intelligent bind parameter dictionary that does type conversions late and preserves the unconverted value; used to fix mappers not comparing correct value in post-fetch [ticket:110]</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1127</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-12 18:24:54 -0600 (Sun, 12 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>refactor to Compiled.get_params() to return new ClauseParameters object, a more intelligent bind parameter dictionary that does type conversions late and preserves the unconverted value; used to fix mappers not comparing correct value in post-fetch [ticket:110] removed pre_exec assertion from oracle/firebird regarding "check for sequence/primary key value" fix to Unicode type to check for null, fixes [ticket:109] create_engine() now uses genericized parameters; host/hostname, db/dbname/database, password/passwd, etc. for all engine connections fix to select([func(column)]) so that it creates a FROM clause to the column's table, fixes [ticket:111] doc updates for column defaults, indexes, connection pooling, engine params unit tests for the above bugfixes</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunkCHANGES">sqlalchemy/trunk/CHANGES</a></li> <li><a href="#sqlalchemytrunkdocbuildcontentdbenginemyt">sqlalchemy/trunk/doc/build/content/dbengine.myt</a></li> <li><a href="#sqlalchemytrunkdocbuildcontentdocstringsmyt">sqlalchemy/trunk/doc/build/content/docstrings.myt</a></li> <li><a href="#sqlalchemytrunkdocbuildcontentdocument_basemyt">sqlalchemy/trunk/doc/build/content/document_base.myt</a></li> <li><a href="#sqlalchemytrunkdocbuildcontentmetadatamyt">sqlalchemy/trunk/doc/build/content/metadata.myt</a></li> <li><a href="#sqlalchemytrunkdocbuildcontentpoolingmyt">sqlalchemy/trunk/doc/build/content/pooling.myt</a></li> <li><a href="#sqlalchemytrunklibsqlalchemyansisqlpy">sqlalchemy/trunk/lib/sqlalchemy/ansisql.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemydatabasesfirebirdpy">sqlalchemy/trunk/lib/sqlalchemy/databases/firebird.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemydatabasesmysqlpy">sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemydatabasesoraclepy">sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemydatabasespostgrespy">sqlalchemy/trunk/lib/sqlalchemy/databases/postgres.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemyenginepy">sqlalchemy/trunk/lib/sqlalchemy/engine.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemymappingmapperpy">sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemyschemapy">sqlalchemy/trunk/lib/sqlalchemy/schema.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemysqlpy">sqlalchemy/trunk/lib/sqlalchemy/sql.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemytypespy">sqlalchemy/trunk/lib/sqlalchemy/types.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemyutilpy">sqlalchemy/trunk/lib/sqlalchemy/util.py</a></li> <li><a href="#sqlalchemytrunksetuppy">sqlalchemy/trunk/setup.py</a></li> <li><a href="#sqlalchemytrunktestindexespy">sqlalchemy/trunk/test/indexes.py</a></li> <li><a href="#sqlalchemytrunktestmapperpy">sqlalchemy/trunk/test/mapper.py</a></li> <li><a href="#sqlalchemytrunktestobjectstorepy">sqlalchemy/trunk/test/objectstore.py</a></li> <li><a href="#sqlalchemytrunktestselectpy">sqlalchemy/trunk/test/select.py</a></li> <li><a href="#sqlalchemytrunktesttestbasepy">sqlalchemy/trunk/test/testbase.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunkCHANGES"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/CHANGES (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/CHANGES 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/CHANGES 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -1,11 +1,46 @@ </span><span class="cx"> 0.1.4 </span><ins>+- create_engine() now uses genericized parameters; host/hostname, db/dbname/database, password/passwd, etc. for all engine connections. makes +engine URIs much more "universal" +- another overhaul to EagerLoading when used in conjunction with mappers that +inherit; improvements to eager loads figuring out their aliased queries +correctly, also relations set up against a mapper with inherited mappers will +create joins against the table that is specific to the mapper itself (i.e. and +not any tables that are inherited/are further down the inheritance chain), +this can be overridden by using custom primary/secondary joins. +- added onupdate parameter to Column, will exec SQL/python upon an update +statement.Also adds "for_update=True" to all DefaultGenerator subclasses +- added rudimentary support for Oracle table reflection. +- checked in an initial Firebird module, awaiting testing. +- added sql.ClauseParameters dictionary object as the result for +compiled.get_params(), does late-typeprocessing of bind parameters so +that the original values are easier to access +- more docs for indexes, column defaults, connection pooling, engine construction +- overhaul to the construction of the types system. uses a simpler inheritance pattern +so that any of the generic types can be easily subclassed, with no need for TypeDecorator. +- added "convert_unicode=False" parameter to SQLEngine, will cause all String types to +perform unicode encoding/decoding (makes Strings act like Unicodes) +- added 'encoding="utf8"' parameter to engine. the given encoding will be +used for all encode/decode calls within Unicode types as well as Strings +when convert_unicode=True. +- improved support to column defaults when used by mappers; mappers will pull +pre-executed defaults from statement's executed bind parameters +(pre-conversion) to populate them into a saved object's attributes; if any +PassiveDefaults have fired off, will instead post-fetch the row from the DB to +populate the object. +- added 'get_session().invalidate(*obj)' method to objectstore, instances will +refresh() themselves upon the next attribute access. +- improvements to SQL func calls including an "engine" keyword argument so +they can be execute()d or scalar()ed standalone, also added func accessor to +SQLEngine </ins><span class="cx"> </span><span class="cx"> 0.1.3 </span><del>-- completed "post_update" feature, will add a second update statement before inserts -and after deletes in order to reconcile a relationship without any dependencies -being created; used when persisting two rows that are dependent on each other -- completed mapper.using(session) function, localized per-object Session functionality; -objects can be declared and manipulated as local to any user-defined Session </del><ins>+- completed "post_update" feature, will add a second update statement before +inserts and after deletes in order to reconcile a relationship without any +dependencies being created; used when persisting two rows that are dependent +on each other +- completed mapper.using(session) function, localized per-object Session +functionality; objects can be declared and manipulated as local to any +user-defined Session </ins><span class="cx"> - fix to Oracle "row_number over" clause with multiple tables </span><span class="cx"> - mapper.get() was not selecting multiple-keyed objects if the mapper's table was a join, </span><span class="cx"> such as in an inheritance relationship, this is fixed. </span></span></pre></div> <a id="sqlalchemytrunkdocbuildcontentdbenginemyt"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/doc/build/content/dbengine.myt (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/doc/build/content/dbengine.myt 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/doc/build/content/dbengine.myt 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -13,17 +13,24 @@ </span><span class="cx"> <p> </span><span class="cx"> Engines exist for SQLite, Postgres, MySQL, and Oracle, using the Pysqlite, Psycopg (1 or 2), MySQLDB, and cx_Oracle modules. Each engine imports its corresponding module which is required to be installed. For Postgres and Oracle, an alternate module may be specified at construction time as well. </span><span class="cx"> </p> </span><del>- <p>An example of connecting to each engine is as follows:</p> </del><ins>+ <p>The string based argument names for connecting are translated to the appropriate names when the connection is made; argument names include "host" or "hostname" for database host, "database", "db", or "dbname" for the database name (also is dsn for Oracle), "user" or "username" for the user, and "password", "pw", or "passwd" for the password. SQLite expects "filename" or "file" for the filename, or if None it defaults to "":memory:".</p> + <p>The connection arguments can be specified as a string + dictionary pair, or a single URL-encoded string, as follows:</p> </ins><span class="cx"> </span><span class="cx"> <&|formatting.myt:code&> </span><span class="cx"> from sqlalchemy import * </span><span class="cx"> </span><span class="cx"> # sqlite in memory </span><span class="cx"> sqlite_engine = create_engine('sqlite', {'filename':':memory:'}, **opts) </span><ins>+ + # via URL + sqlite_engine = create_engine('sqlite://', **opts) </ins><span class="cx"> </span><span class="cx"> # sqlite using a file </span><span class="cx"> sqlite_engine = create_engine('sqlite', {'filename':'querytest.db'}, **opts) </span><span class="cx"> </span><ins>+ # via URL + sqlite_engine = create_engine('sqlite://filename=querytest.db', **opts) + </ins><span class="cx"> # postgres </span><span class="cx"> postgres_engine = create_engine('postgres', </span><span class="cx"> {'database':'test', </span><span class="lines">@@ -31,6 +38,9 @@ </span><span class="cx"> 'user':'scott', </span><span class="cx"> 'password':'tiger'}, **opts) </span><span class="cx"> </span><ins>+ # via URL + postgres_engine = create_engine('postgres://database=test&amp;host=127.0.0.1&amp;user=scott&amp;password=tiger') + </ins><span class="cx"> # mysql </span><span class="cx"> mysql_engine = create_engine('mysql', </span><span class="cx"> { </span><span class="lines">@@ -49,20 +59,17 @@ </span><span class="cx"> </span><span class="cx"> </&> </span><span class="cx"> <p>Note that the general form of connecting to an engine is:</p> </span><del>- <&|formatting.myt:code&> </del><ins>+ <&|formatting.myt:code &> + # separate arguments </ins><span class="cx"> engine = create_engine( </span><span class="cx"> <enginename>, </span><span class="cx"> {<named DBAPI arguments>}, </span><del>- <sqlalchemy options> </del><ins>+ <sqlalchemy options>; </ins><span class="cx"> ) </span><ins>+ + # url + engine = create_engine('&lt;enginename&gt;://&lt;named DBAPI arguments&gt;', <sqlalchemy options>) </ins><span class="cx"> </&> </span><del>- <p>The second argument is a dictionary whose key/value pairs will be passed to the underlying DBAPI connect() method as keyword arguments. Any keyword argument supported by the DBAPI module can be in this dictionary.</p> - <p>Engines can also be loaded by URL. The above format is converted into <span class="codeline"><% '<enginename>://key=val&key=val' |h %></span>: - <&|formatting.myt:code&> - sqlite_engine = create_engine('sqlite://filename=querytest.db') - postgres_engine = create_engine('postgres://database=test&user=scott&password=tiger') - </&> - </p> </del><span class="cx"> </&> </span><span class="cx"> <&|doclib.myt:item, name="methods", description="Database Engine Methods" &> </span><span class="cx"> <p>A few useful methods off the SQLEngine are described here:</p> </span><span class="lines">@@ -95,7 +102,18 @@ </span><span class="cx"> <&|doclib.myt:item, name="options", description="Database Engine Options" &> </span><span class="cx"> <p>The remaining arguments to <span class="codeline">create_engine</span> are keyword arguments that are passed to the specific subclass of <span class="codeline">sqlalchemy.engine.SQLEngine</span> being used, as well as the underlying <span class="codeline">sqlalchemy.pool.Pool</span> instance. All of the options described in the previous section <&formatting.myt:link, path="pooling_configuration"&> can be specified, as well as engine-specific options:</p> </span><span class="cx"> <ul> </span><del>- <li>pool=None : an instance of <span class="codeline">sqlalchemy.pool.DBProxy</span> to be used as the underlying source for connections (DBProxy is described in the previous section). If None, a default DBProxy will be created using the engine's own database module with the given arguments.</li> </del><ins>+ <li><p>pool=None : an instance of <span class="codeline">sqlalchemy.pool.Pool</span> to be used as the underlying source for connections, overriding the engine's connect arguments (pooling is described in the previous section). If None, a default Pool (QueuePool or SingletonThreadPool as appropriate) will be created using the engine's connect arguments.</p> + <p>Example:</p> + <&|formatting.myt:code&> + from sqlalchemy import * + import sqlalchemy.pool as pool + import MySQLdb + + def getconn(): + return MySQLdb.connect(user='ed', dbname='mydb') + + engine = create_engine('mysql', pool=pool.QueuePool(getconn, pool_size=20, max_overflow=40)) + </&></li> </ins><span class="cx"> <li>echo=False : if True, the SQLEngine will log all statements as well as a repr() of their parameter lists to the engines logger, which defaults to sys.stdout. A SQLEngine instances' "echo" data member can be modified at any time to turn logging on and off. If set to the string 'debug', result rows will be printed to the standard output as well.</li> </span><span class="cx"> <li>logger=None : a file-like object where logging output can be sent, if echo is set to True. This defaults to sys.stdout.</li> </span><span class="cx"> <li>module=None : used by Oracle and Postgres, this is a reference to a DBAPI2 module to be used instead of the engine's default module. For Postgres, the default is psycopg2, or psycopg1 if 2 cannot be found. For Oracle, its cx_Oracle.</li> </span><span class="lines">@@ -103,7 +121,8 @@ </span><span class="cx"> <li>use_ansi=True : used only by Oracle; when False, the Oracle driver attempts to support a particular "quirk" of some Oracle databases, that the LEFT OUTER JOIN SQL syntax is not supported, and the "Oracle join" syntax of using <% "<column1>(+)=<column2>" |h%> must be used in order to achieve a LEFT OUTER JOIN. Its advised that the Oracle database be configured to have full ANSI support instead of using this feature.</li> </span><span class="cx"> <li>use_oids=False : used only by Postgres, will enable the column name "oid" as the object ID column. Postgres as of 8.1 has object IDs disabled by default.</li> </span><span class="cx"> <li>convert_unicode=False : if set to True, all String/character based types will convert Unicode values to raw byte values going into the database, and all raw byte values to Python Unicode coming out in result sets. This is an engine-wide method to provide unicode across the board. For unicode conversion on a column-by-column level, use the Unicode column type instead.</li> </span><del>- <li>encoding='utf-8' : the encoding to use when doing unicode translations.</li> </del><ins>+ <li>encoding='utf-8' : the encoding to use for Unicode translations - passed to all encode/decode functions.</li> + <li>echo_uow=False : when True, logs unit of work commit plans to the standard output.</li> </ins><span class="cx"> </ul> </span><span class="cx"> </&> </span><span class="cx"> <&|doclib.myt:item, name="proxy", description="Using the Proxy Engine" &> </span></span></pre></div> <a id="sqlalchemytrunkdocbuildcontentdocstringsmyt"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/doc/build/content/docstrings.myt (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/doc/build/content/docstrings.myt 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/doc/build/content/docstrings.myt 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -14,7 +14,7 @@ </span><span class="cx"> </span><span class="cx"> <& pydoc.myt:obj_doc, obj=schema &> </span><span class="cx"> <& pydoc.myt:obj_doc, obj=engine, classes=[engine.SQLEngine, engine.ResultProxy, engine.RowProxy] &> </span><del>-<& pydoc.myt:obj_doc, obj=sql, classes=[sql.Compiled, sql.ClauseElement, sql.TableClause, sql.ColumnClause] &> </del><ins>+<& pydoc.myt:obj_doc, obj=sql, classes=[sql.ClauseParameters, sql.Compiled, sql.ClauseElement, sql.TableClause, sql.ColumnClause] &> </ins><span class="cx"> <& pydoc.myt:obj_doc, obj=pool, classes=[pool.DBProxy, pool.Pool, pool.QueuePool, pool.SingletonThreadPool] &> </span><span class="cx"> <& pydoc.myt:obj_doc, obj=mapping &> </span><span class="cx"> <& pydoc.myt:obj_doc, obj=mapping.objectstore, classes=[mapping.objectstore.Session, mapping.objectstore.Session.SessionTrans, mapping.objectstore.UnitOfWork] &> </span></span></pre></div> <a id="sqlalchemytrunkdocbuildcontentdocument_basemyt"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/doc/build/content/document_base.myt (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/doc/build/content/document_base.myt 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/doc/build/content/document_base.myt 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -23,7 +23,7 @@ </span><span class="cx"> onepage='documentation' </span><span class="cx"> index='index' </span><span class="cx"> title='SQLAlchemy Documentation' </span><del>- version = '0.1.3' </del><ins>+ version = '0.1.4' </ins><span class="cx"> </%attr> </span><span class="cx"> </span><span class="cx"> <%method title> </span></span></pre></div> <a id="sqlalchemytrunkdocbuildcontentmetadatamyt"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/doc/build/content/metadata.myt (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/doc/build/content/metadata.myt 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/doc/build/content/metadata.myt 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -107,15 +107,11 @@ </span><span class="cx"> >>> othertable is news_articles </span><span class="cx"> True </span><span class="cx"> </&> </span><del>- - - </del><span class="cx"> </&> </span><span class="cx"> <&|doclib.myt:item, name="creating", description="Creating and Dropping Database Tables" &> </span><span class="cx"> <p>Creating and dropping is easy, just use the <span class="codeline">create()</span> and <span class="codeline">drop()</span> methods: </span><span class="cx"> <&|formatting.myt:code&> </span><del>- <&formatting.myt:poplink&> - employees = Table('employees', engine, </del><ins>+ <&formatting.myt:poplink&>employees = Table('employees', engine, </ins><span class="cx"> Column('employee_id', Integer, primary_key=True), </span><span class="cx"> Column('employee_name', String(60), nullable=False, key='name'), </span><span class="cx"> Column('employee_dept', Integer, ForeignKey("departments.department_id")) </span><span class="lines">@@ -126,18 +122,162 @@ </span><span class="cx"> employee_name VARCHAR(60) NOT NULL, </span><span class="cx"> employee_dept INTEGER REFERENCES departments(department_id) </span><span class="cx"> ) </span><ins>+{} </&> </ins><span class="cx"> </span><del>-{} </&> - - <&formatting.myt:poplink&> - employees.drop() <&|formatting.myt:codepopper, link="sql" &> </del><ins>+ <&formatting.myt:poplink&>employees.drop() <&|formatting.myt:codepopper, link="sql" &> </ins><span class="cx"> DROP TABLE employees </span><span class="cx"> {} </&> </span><span class="cx"> </&> </span><span class="cx"> </&> </span><span class="cx"> </span><ins>+ + <&|doclib.myt:item, name="defaults", description="Column Defaults and OnUpdates" &> + <p>SQLAlchemy includes flexible constructs in which to create default values for columns upon the insertion of rows, as well as upon update. These defaults can take several forms: a constant, a Python callable to be pre-executed before the SQL is executed, a SQL expression or function to be pre-executed before the SQL is executed, a pre-executed Sequence (for databases that support sequences), or a "passive" default, which is a default function triggered by the database itself upon insert, the value of which can then be post-fetched by the engine, provided the row provides a primary key in which to call upon.</p> + <&|doclib.myt:item, name="oninsert", description="Pre-Executed Insert Defaults" &> + <p>A basic default is most easily specified by the "default" keyword argument to Column:</p> + <&|formatting.myt:code&> + # a function to create primary key ids + i = 0 + def mydefault(): + i += 1 + return i + + t = Table("mytable", db, + # function-based default + Column('id', Integer, primary_key=True, default=mydefault), + + # a scalar default + Column('key', String(10), default="default") + ) + </&> + <p>The "default" keyword can also take SQL expressions, including select statements or direct function calls:</p> + <&|formatting.myt:code&> + t = Table("mytable", db, + Column('id', Integer, primary_key=True), + + # define 'create_date' to default to now() + Column('create_date', DateTime, default=func.now()), + + # define 'key' to pull its default from the 'keyvalues' table + Column('key', String(20), default=keyvalues.select(keyvalues.c.type='type1', limit=1)) + ) + </&> + <p>The "default" keyword argument is shorthand for using a ColumnDefault object in a column definition. This syntax is optional, but is required for other types of defaults, futher described below:</p> + <&|formatting.myt:code&> + Column('mycolumn', String(30), ColumnDefault(func.get_data())) + </&> + </&> + + <&|doclib.myt:item, name="onupdate", description="Pre-Executed OnUpdate Defaults" &> + <p>Similar to an on-insert default is an on-update default, which is most easily specified by the "onupdate" keyword to Column, which also can be a constanct, plain Python function or SQL expression:</p> + <&|formatting.myt:code&> + t = Table("mytable", db, + Column('id', Integer, primary_key=True), + + # define 'last_updated' to be populated with current_timestamp (the ANSI-SQL version of now()) + Column('last_updated', DateTime, onupdate=func.current_timestamp()), + ) + </&> + <p>To use a ColumnDefault explicitly for an on-update, use the "for_update" keyword argument:</p> + <&|formatting.myt:code&> + Column('mycolumn', String(30), ColumnDefault(func.get_data(), for_update=True)) + </&> + </&> + + <&|doclib.myt:item, name="passive", description="Inline Default Execution: PassiveDefault" &> + <p>A PassiveDefault indicates a column default or on-update value that is executed automatically by the database. This construct is used to specify a SQL function that will be specified as "DEFAULT" when creating tables, and also to indicate the presence of new data that is available to be "post-fetched" after an insert or update execution.</p> + <&|formatting.myt:code&> + t = Table('test', e, + Column('mycolumn', DateTime, PassiveDefault("sysdate")) + ) + </&> + <p>A create call for the above table will produce:</p> + <&|formatting.myt:code&> + CREATE TABLE test ( + mycolumn datetime default sysdate + ) + </&> + <p>PassiveDefaults also send a message to the SQLEngine that data is available after update or insert. The object-relational mapper system uses this information to post-fetch rows after insert or update, so that instances can be refreshed with the new data. Below is a simplified version:</p> + <&|formatting.myt:code&> + # table with passive defaults + mytable = Table('mytable', engine, + Column('my_id', Integer, primary_key=True), + + # an on-insert database-side default + Column('data1', Integer, PassiveDefault("d1_func")), + + # an on-update database-side default + Column('data2', Integer, PassiveDefault("d2_func", for_update=True)) + ) + # insert a row + mytable.insert().execute(name='fred') + + # ask the engine: were there defaults fired off on that row ? + if table.engine.lastrow_has_defaults(): + # postfetch the row based on primary key. + # this only works for a table with primary key columns defined + primary_key = table.engine.last_inserted_ids() + row = table.select(table.c.id == primary_key[0]) + </&> + <p>Tables that are reflected from the database which have default values set on them, will receive those defaults as PassiveDefaults.</p> + + <&|doclib.myt:item, name="postgres", description="The Catch: Postgres Primary Key Defaults always Pre-Execute" &> + <p>Current Postgres support does not rely upon OID's to determine the identity of a row. This is because the usage of OIDs has been deprecated with Postgres and they are disabled by default for table creates as of PG version 8. Pyscopg2's "cursor.lastrowid" function only returns OIDs. Therefore, when inserting a new row which has passive defaults set on the primary key columns, the default function is <b>still pre-executed</b> since SQLAlchemy would otherwise have no way of retrieving the row just inserted.</p> + </&> + </&> + <&|doclib.myt:item, name="sequences", description="Defining Sequences" &> + <P>A table with a sequence looks like:</p> + <&|formatting.myt:code&> + table = Table("cartitems", db, + Column("cart_id", Integer, Sequence('cart_id_seq'), primary_key=True), + Column("description", String(40)), + Column("createdate", DateTime()) + ) + </&> + <p>The Sequence is used with Postgres or Oracle to indicate the name of a Sequence that will be used to create default values for a column. When a table with a Sequence on a column is created by SQLAlchemy, the Sequence object is also created. Similarly, the Sequence is dropped when the table is dropped. Sequences are typically used with primary key columns. When using Postgres, if an integer primary key column defines no explicit Sequence or other default method, SQLAlchemy will create the column with the SERIAL keyword, and will pre-execute a sequence named "tablename_columnname_seq" in order to retrieve new primary key values. Oracle, which has no "auto-increment" keyword, requires that a Sequence be created for a table if automatic primary key generation is desired. Note that for all databases, primary key values can always be explicitly stated within the bind parameters for any insert statement as well, removing the need for an! y kind of default generation function.</p> + + <p>A Sequence object can be defined on a Table that is then used for a non-sequence-supporting database. In that case, the Sequence object is simply ignored. Note that a Sequence object is <b>entirely optional for all databases except Oracle</b>, as other databases offer options for auto-creating primary key values, such as AUTOINCREMENT, SERIAL, etc. SQLAlchemy will use these default methods for creating primary key values if no Sequence is present on the table metadata.</p> + + <p>A sequence can also be specified with <span class="codeline">optional=True</span> which indicates the Sequence should only be used on a database that requires an explicit sequence, and not those that supply some other method of providing integer values. At the moment, it essentially means "use this sequence only with Oracle and not Postgres".</p> + </&> + </&> + <&|doclib.myt:item, name="indexes", description="Defining Indexes" &> + <p>Indexes can be defined on table columns, including named indexes, non-unique or unique, multiple column. Indexes are included along with table create and drop statements. They are not used for any kind of run-time constraint checking...SQLAlchemy leaves that job to the expert on constraint checking, the database itself.</p> + <&|formatting.myt:code&> + mytable = Table('mytable', engine, + + # define a unique index + Column('col1', Integer, unique=True), + + # define a unique index with a specific name + Column('col2', Integer, unique='mytab_idx_1'), + + # define a non-unique index + Column('col3', Integer, index=True), + + # define a non-unique index with a specific name + Column('col4', Integer, index='mytab_idx_2'), + + # pass the same name to multiple columns to add them to the same index + Column('col5', Integer, index='mytab_idx_2'), + + Column('col6', Integer), + Column('col7', Integer) + ) + + # create the table. all the indexes will be created along with it. + mytable.create() + + # indexes can also be specified standalone + i = Index('mytab_idx_3', mytable.c.col6, mytable.c.col7, unique=False) + + # which can then be created separately (will also get created with table creates) + i.create() + + </&> + </&> </ins><span class="cx"> <&|doclib.myt:item, name="adapting", description="Adapting Tables to Alternate Engines" &> </span><del>- <p>Occasionally an application will need to reference the same tables within multiple databases simultaneously. Since a Table object is specific to a SQLEngine, an extra method is provided to create copies of the Table object for a different SQLEngine instance, which can represent a different set of connection parameters, or a totally different database driver: </del><ins>+ <p>A Table object created against a specific engine can be re-created against a new engine using the <span class="codeline">toengine</span> method:</p> </ins><span class="cx"> </span><span class="cx"> <&|formatting.myt:code&> </span><span class="cx"> # create two engines </span><span class="lines">@@ -153,7 +293,7 @@ </span><span class="cx"> pg_users = users.toengine(postgres_engine) </span><span class="cx"> </&> </span><span class="cx"> </span><del>- <p>You can also create tables using a "database neutral" engine, which can serve as a starting point for tables that are then adapted to specific engines:</p> </del><ins>+ <p>Also available is the "database neutral" ansisql engine:</p> </ins><span class="cx"> <&|formatting.myt:code&> </span><span class="cx"> import sqlalchemy.ansisql as ansisql </span><span class="cx"> generic_engine = ansisql.engine() </span><span class="lines">@@ -162,30 +302,27 @@ </span><span class="cx"> Column('user_id', Integer), </span><span class="cx"> Column('user_name', String(50)) </span><span class="cx"> ) </span><ins>+ </&> + <p>Flexible "multi-engined" tables can also be achieved via the proxy engine, described in the section <&formatting.myt:link, path="dbengine_proxy"&>.</p> </ins><span class="cx"> </span><del>- sqlite_engine = create_engine('sqlite', {'filename':'querytest.db'}) - sqlite_users = users.toengine(sqlite_engine) - sqlite_users.create() - </&> </del><ins>+ <&|doclib.myt:item, name="primitives", description="Non-engine primitives: TableClause/ColumnClause" &> + + <p>TableClause and ColumnClause are "primitive" versions of the Table and Column objects which dont use engines at all; applications that just want to generate SQL strings but not directly communicate with a database can use TableClause and ColumnClause objects, which are non-singleton and serve as the "lexical" base class of Table and Column:</p> + <&|formatting.myt:code&> + tab1 = TableClause('table1', + ColumnClause('id'), + ColumnClause('name')) + + tab2 = TableClause('table2', + ColumnClause('id'), + ColumnClause('email')) + + tab1.select(tab1.c.name == 'foo') + </&> </ins><span class="cx"> </span><ins>+ <p>TableClause and ColumnClause are strictly lexical. This means they are fully supported within the full range of SQL statement generation, but they don't support schema concepts like creates, drops, primary keys, defaults, nullable status, indexes, or foreign keys.</p> </ins><span class="cx"> </&> </span><ins>+ </&> </ins><span class="cx"> </span><del>- <&|doclib.myt:item, name="sequences", description="Defining Sequences" &> - <P>A table with a sequence looks like:</p> - <&|formatting.myt:code&> - table = Table("cartitems", db, - Column("cart_id", Integer, Sequence('cart_id_seq'), primary_key=True), - Column("description", String(40)), - Column("createdate", DateTime()) - ) - </&> - <p>The Sequence is used when a Postgres or Oracle database schema defines a sequence of a specific name which must be used to create integer values. If a Sequence is not defined, Postgres will default to regular SERIAL access. Oracle currently has no default primary key method; so explicit primary key values or Sequence objects are required to insert new rows.</p> </del><span class="cx"> </span><del>-<p>Defining a Sequence means that it will be created along with the table.create() call, and that the sequence will be explicitly used when inserting new rows for this table, for databases that support sequences. If the Table is connected to a database that doesnt support sequences, the Sequence object is simply ignored. Note that a Sequence object is <b>entirely optional for all databases except Oracle</b>, as other databases offer options for auto-creating primary key values, such as AUTOINCREMENT, SERIAL, etc. SQLAlchemy will use these default methods for creating primary key values if no Sequence is present on the table metadata.</p> - -<p>A sequence can also be specified with <span class="codeline">optional=True</span> which indicates the Sequence should only be used on a database that requires an explicit sequence, and not those that supply some other method of providing integer values. At the moment, it essentially means "use this sequence only with Oracle and not Postgres".</p> - -<p>More docs TODO in this area include the ColumnDefault and PassiveDefault objects which provide more options to automatic generation of column values.</p> - </&> - </del><span class="cx"> </&> </span></span></pre></div> <a id="sqlalchemytrunkdocbuildcontentpoolingmyt"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/doc/build/content/pooling.myt (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/doc/build/content/pooling.myt 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/doc/build/content/pooling.myt 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -27,10 +27,40 @@ </span><span class="cx"> </p> </span><span class="cx"> <ul> </span><span class="cx"> <li>echo=False : if set to True, connections being pulled and retrieved from/to the pool will be logged to the standard output, as well as pool sizing information.</li> </span><del>- <li>use_threadlocal=True : if set to True, repeated calls to connect() within the same application thread will be guaranteed to return the <b>same</b> connection object, if one has already been retrieved from the pool and has not been returned yet. This allows code to retrieve a connection from the pool, and then while still holding on to that connection, to call other functions which also ask the pool for a connection of the same arguments; those functions will act upon the same connection that the calling method is using.</li> - <li>poolclass=QueuePool : the Pool class used by the pool module to provide pooling. QueuePool uses the Python <span class="codeline">Queue.Queue</span> class to maintain a list of available connections. A developer can supply his or her own Pool class to supply a different pooling algorithm.</li> </del><ins>+ <li>use_threadlocal=True : if set to True, repeated calls to connect() within the same application thread will be guaranteed to return the <b>same</b> connection object, if one has already been retrieved from the pool and has not been returned yet. This allows code to retrieve a connection from the pool, and then while still holding on to that connection, to call other functions which also ask the pool for a connection of the same arguments; those functions will act upon the same connection that the calling method is using. Note that once the connection is returned to the pool, it then may be used by another thread. To guarantee a single unique connection per thread that <b>never</b> changes, use the option <span class="codeline">poolclass=SingletonThreadPool</span>, in which case the use_threadlocal parameter is automatically set to False.</li> + <li>poolclass=QueuePool : the Pool class used by the pool module to provide pooling. QueuePool uses the Python <span class="codeline">Queue.Queue</span> class to maintain a list of available connections. A developer can supply his or her own Pool class to supply a different pooling algorithm. Also included is the ThreadSingletonPool, which provides a single distinct connection per thread and is required with SQLite.</li> </ins><span class="cx"> <li>pool_size=5 : used by QueuePool - the size of the pool to be maintained. This is the largest number of connections that will be kept persistently in the pool. Note that the pool begins with no connections; once this number of connections is requested, that number of connections will remain.</li> </span><del>- <li>max_overflow=10 : the maximum overflow size of the pool. When the number of checked-out connections reaches the size set in pool_size, additional connections will be returned up to this limit. When those additional connections are returned to the pool, they are disconnected and discarded. It follows then that the total number of simultaneous connections the pool will allow is pool_size + max_overflow, and the total number of "sleeping" connections the pool will allow is pool_size. max_overflow can be set to -1 to indicate no overflow limit; no limit will be placed on the total number of concurrent connections.</li> </del><ins>+ <li>max_overflow=10 : used by QueuePool - the maximum overflow size of the pool. When the number of checked-out connections reaches the size set in pool_size, additional connections will be returned up to this limit. When those additional connections are returned to the pool, they are disconnected and discarded. It follows then that the total number of simultaneous connections the pool will allow is pool_size + max_overflow, and the total number of "sleeping" connections the pool will allow is pool_size. max_overflow can be set to -1 to indicate no overflow limit; no limit will be placed on the total number of concurrent connections.</li> </ins><span class="cx"> </ul> </span><span class="cx"> </&> </span><ins>+ + <&|doclib.myt:item, name="custom", description="Custom Pool Construction" &> + <p>One level below using a DBProxy to make transparent pools is creating the pool yourself. The pool module comes with two implementations of connection pools: <span class="codeline">QueuePool</span> and <span class="codeline">SingletonThreadPool</span>. While QueuePool uses Queue.Queue to provide connections, SingletonThreadPool provides a single per-thread connection which SQLite requires.</p> + + <p>Constructing your own pool involves passing a callable used to create a connection. Through this method, custom connection schemes can be made, such as a connection that automatically executes some initialization commands to start. The options from the previous section can be used as they apply to QueuePool or SingletonThreadPool.</p> + <&|formatting.myt:code, title="Plain QueuePool"&> + import sqlalchemy.pool as pool + import psycopg2 + + def getconn(): + c = psycopg2.connect(username='ed', host='127.0.0.1', dbname='test') + # execute an initialization function on the connection before returning + c.cursor.execute("setup_encodings()") + return c + + p = pool.QueuePool(getconn, max_overflow=10, pool_size=5, use_threadlocal=True) + </&> + + <&|formatting.myt:code, title="SingletonThreadPool"&> + import sqlalchemy.pool as pool + import sqlite + + def getconn(): + return sqlite.connect(filename='myfile.db') + + # SQLite connections require the SingletonThreadPool + p = pool.SingletonThreadPool(getconn) + </&> + + </&> </ins><span class="cx"> </&> </span><span class="cx">\ No newline at end of file </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemyansisqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/ansisql.py (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/ansisql.py 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/lib/sqlalchemy/ansisql.py 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -118,7 +118,8 @@ </span><span class="cx"> objects compiled within this object. The output is dependent on the paramstyle </span><span class="cx"> of the DBAPI being used; if a named style, the return result will be a dictionary </span><span class="cx"> with keynames matching the compiled statement. If a positional style, the output </span><del>- will be a list corresponding to the bind positions in the compiled statement. </del><ins>+ will be a list, with an iterator that will return parameter + values in an order corresponding to the bind positions in the compiled statement. </ins><span class="cx"> </span><span class="cx"> for an executemany style of call, this method should be called for each element </span><span class="cx"> in the list of parameter groups that will ultimately be executed. </span><span class="lines">@@ -129,32 +130,23 @@ </span><span class="cx"> bindparams = {} </span><span class="cx"> bindparams.update(params) </span><span class="cx"> </span><ins>+ d = sql.ClauseParameters(self.engine) </ins><span class="cx"> if self.positional: </span><del>- d = OrderedDict() </del><span class="cx"> for k in self.positiontup: </span><span class="cx"> b = self.binds[k] </span><del>- if self.engine is not None: - d[k] = b.typeprocess(b.value, self.engine) - else: - d[k] = b.value </del><ins>+ d.set_parameter(k, b.value, b) </ins><span class="cx"> else: </span><del>- d = {} </del><span class="cx"> for b in self.binds.values(): </span><del>- if self.engine is not None: - d[b.key] = b.typeprocess(b.value, self.engine) - else: - d[b.key] = b.value </del><ins>+ d.set_parameter(b.key, b.value, b) </ins><span class="cx"> </span><span class="cx"> for key, value in bindparams.iteritems(): </span><span class="cx"> try: </span><span class="cx"> b = self.binds[key] </span><span class="cx"> except KeyError: </span><span class="cx"> continue </span><del>- if self.engine is not None: - d[b.key] = b.typeprocess(value, self.engine) - else: - d[b.key] = value </del><ins>+ d.set_parameter(b.key, value, b) </ins><span class="cx"> </span><ins>+ #print "FROM", params, "TO", d </ins><span class="cx"> return d </span><span class="cx"> </span><span class="cx"> def get_named_params(self, parameters): </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemydatabasesfirebirdpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/firebird.py (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/firebird.py 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/firebird.py 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -176,19 +176,8 @@ </span><span class="cx"> return self.context.last_inserted_ids </span><span class="cx"> </span><span class="cx"> def pre_exec(self, proxy, compiled, parameters, **kwargs): </span><del>- # this is just an assertion that all the primary key columns in an insert statement - # have a value set up, or have a default generator ready to go - if getattr(compiled, "isinsert", False): - if isinstance(parameters, list): - plist = parameters - else: - plist = [parameters] - for param in plist: - for primary_key in compiled.statement.table.primary_key: - if not param.has_key(primary_key.key) or param[primary_key.key] is None: - if primary_key.default is None: - raise "Column '%s.%s': Firebird primary key columns require a default value or a schema.Sequence to create ids" % (primary_key.table.name, primary_key.name) - </del><ins>+ pass + </ins><span class="cx"> def _executemany(self, c, statement, parameters): </span><span class="cx"> rowcount = 0 </span><span class="cx"> for param in parameters: </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemydatabasesmysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -134,7 +134,7 @@ </span><span class="cx"> def __init__(self, opts, module = None, **params): </span><span class="cx"> if module is None: </span><span class="cx"> self.module = mysql </span><del>- self.opts = opts or {} </del><ins>+ self.opts = self._translate_connect_args(('host', 'db', 'user', 'passwd'), opts) </ins><span class="cx"> ansisql.ANSISQLEngine.__init__(self, **params) </span><span class="cx"> </span><span class="cx"> def connect_args(self): </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemydatabasesoraclepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -90,7 +90,7 @@ </span><span class="cx"> class OracleSQLEngine(ansisql.ANSISQLEngine): </span><span class="cx"> def __init__(self, opts, use_ansi = True, module = None, **params): </span><span class="cx"> self._use_ansi = use_ansi </span><del>- self.opts = opts or {} </del><ins>+ self.opts = self._translate_connect_args((None, 'dsn', 'user', 'password'), opts) </ins><span class="cx"> if module is None: </span><span class="cx"> self.module = cx_Oracle </span><span class="cx"> else: </span><span class="lines">@@ -181,18 +181,7 @@ </span><span class="cx"> return self.context.last_inserted_ids </span><span class="cx"> </span><span class="cx"> def pre_exec(self, proxy, compiled, parameters, **kwargs): </span><del>- # this is just an assertion that all the primary key columns in an insert statement - # have a value set up, or have a default generator ready to go - if getattr(compiled, "isinsert", False): - if isinstance(parameters, list): - plist = parameters - else: - plist = [parameters] - for param in plist: - for primary_key in compiled.statement.table.primary_key: - if not param.has_key(primary_key.key) or param[primary_key.key] is None: - if primary_key.default is None: - raise "Column '%s.%s': Oracle primary key columns require a default value or a schema.Sequence to create ids" % (primary_key.table.name, primary_key.name) </del><ins>+ pass </ins><span class="cx"> </span><span class="cx"> def _executemany(self, c, statement, parameters): </span><span class="cx"> rowcount = 0 </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemydatabasespostgrespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/postgres.py (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/postgres.py 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/postgres.py 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -181,7 +181,7 @@ </span><span class="cx"> self.version = 1 </span><span class="cx"> except: </span><span class="cx"> self.version = 1 </span><del>- self.opts = opts or {} </del><ins>+ self.opts = self._translate_connect_args(('host', 'database', 'user', 'password'), opts) </ins><span class="cx"> if self.opts.has_key('port'): </span><span class="cx"> if self.version == 2: </span><span class="cx"> self.opts['port'] = int(self.opts['port']) </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemyenginepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/engine.py (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/engine.py 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/lib/sqlalchemy/engine.py 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -203,6 +203,25 @@ </span><span class="cx"> self._figure_paramstyle() </span><span class="cx"> self.logger = logger or util.Logger(origin='engine') </span><span class="cx"> </span><ins>+ def _translate_connect_args(self, names, args): + """translates a dictionary of connection arguments to those used by a specific dbapi. + the names parameter is a tuple of argument names in the form ('host', 'database', 'user', 'password') + where the given strings match the corresponding argument names for the dbapi. Will return a dictionary + with the dbapi-specific parameters, the generic ones removed, and any additional parameters still remaining, + from the dictionary represented by args. Will return a blank dictionary if args is null.""" + if args is None: + return {} + a = args.copy() + standard_names = [('host','hostname'), ('database', 'dbname'), ('user', 'username'), ('password', 'passwd', 'pw')] + for n in names: + sname = standard_names.pop(0) + if n is None: + continue + for sn in sname: + if sn != n and a.has_key(sn): + a[n] = a[sn] + del a[sn] + return a </ins><span class="cx"> def _get_ischema(self): </span><span class="cx"> # We use a property for ischema so that the accessor </span><span class="cx"> # creation only happens as needed, since otherwise we </span><span class="lines">@@ -563,7 +582,6 @@ </span><span class="cx"> parameters = [compiled.get_params(**m) for m in parameters] </span><span class="cx"> else: </span><span class="cx"> parameters = compiled.get_params(**parameters) </span><del>- </del><span class="cx"> def proxy(statement=None, parameters=None): </span><span class="cx"> if statement is None: </span><span class="cx"> return cursor </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemymappingmapperpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py (1126 => 1127)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-10 05:03:17 UTC (rev 1126) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-13 00:24:54 UTC (rev 1127) </span><span class="lines">@@ -651,8 +651,8 @@ </span><span class="cx"> for c in table.c: </span><span class="cx"> if c.primary_key or not params.has_key(c.name): </span><span class="cx"> continue </span><del>- if self._getattrbycolumn(obj, c) != params[c.name]: - self._setattrbycolumn(obj, c, params[c.name]) </del><ins>+ if self._getattrbycolumn(obj, c) != params.get_original(c.name): + self._setattrbycolumn(obj, c, params.get_original(c.name)) </ins><span class="cx"> </span><span class="cx"> def delete_obj(self, objects, uow): </span><s... [truncated message content] |
From: <co...@sq...> - 2006-03-10 05:03:29
|
<!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>[1126] sqlalchemy/trunk/test: added expire() function + unit test fixes [ticket:95]</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1126</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 23:03:17 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>added expire() function + unit test fixes [ticket:95]</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemyattributespy">sqlalchemy/trunk/lib/sqlalchemy/attributes.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemymappingobjectstorepy">sqlalchemy/trunk/lib/sqlalchemy/mapping/objectstore.py</a></li> <li><a href="#sqlalchemytrunktestmapperpy">sqlalchemy/trunk/test/mapper.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemyattributespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/attributes.py (1125 => 1126)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/attributes.py 2006-03-10 04:47:38 UTC (rev 1125) +++ sqlalchemy/trunk/lib/sqlalchemy/attributes.py 2006-03-10 05:03:17 UTC (rev 1126) </span><span class="lines">@@ -353,10 +353,20 @@ </span><span class="cx"> try: </span><span class="cx"> attr = obj.__dict__['_managed_attributes'] </span><span class="cx"> except KeyError: </span><ins>+ trigger = obj.__dict__.pop('_managed_trigger', None) + if trigger: + trigger() </ins><span class="cx"> attr = {} </span><span class="cx"> obj.__dict__['_managed_attributes'] = attr </span><span class="cx"> return attr </span><span class="cx"> </span><ins>+ def trigger_history(self, obj, callable): + try: + del obj.__dict__['_managed_attributes'] + except KeyError: + pass + obj.__dict__['_managed_trigger'] = callable + </ins><span class="cx"> def reset_history(self, obj, key): </span><span class="cx"> """removes the history object for the given attribute on the given object. </span><span class="cx"> When the attribute is next accessed, a new container will be created via the </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemymappingobjectstorepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/objectstore.py (1125 => 1126)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/objectstore.py 2006-03-10 04:47:38 UTC (rev 1125) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/objectstore.py 2006-03-10 05:03:17 UTC (rev 1126) </span><span class="lines">@@ -145,9 +145,17 @@ </span><span class="cx"> self.uow.commit() </span><span class="cx"> </span><span class="cx"> def refresh(self, *obj): </span><ins>+ """reloads the attributes for the given objects from the database, clears + any changes made.""" </ins><span class="cx"> for o in obj: </span><span class="cx"> self.uow.refresh(o) </span><span class="cx"> </span><ins>+ def expire(self, *obj): + """invalidates the data in the given objects and sets them to refresh themselves + the next time they are requested.""" + for o in obj: + global_attributes.trigger_history(o, lambda: refresh(o)) + </ins><span class="cx"> def register_clean(self, obj): </span><span class="cx"> self._bind_to(obj) </span><span class="cx"> self.uow.register_clean(obj) </span><span class="lines">@@ -229,6 +237,11 @@ </span><span class="cx"> """reloads the state of this object from the database, and cancels any in-memory </span><span class="cx"> changes.""" </span><span class="cx"> get_session().refresh(*obj) </span><ins>+ +def expire(*obj): + """invalidates the data in the given objects and sets them to refresh themselves + the next time they are requested.""" + get_session().expire(*obj) </ins><span class="cx"> </span><span class="cx"> def delete(*obj): </span><span class="cx"> """registers the given objects as to be deleted upon the next commit""" </span></span></pre></div> <a id="sqlalchemytrunktestmapperpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/mapper.py (1125 => 1126)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/mapper.py 2006-03-10 04:47:38 UTC (rev 1125) +++ sqlalchemy/trunk/test/mapper.py 2006-03-10 05:03:17 UTC (rev 1126) </span><span class="lines">@@ -84,6 +84,31 @@ </span><span class="cx"> u2 = m.get(7) </span><span class="cx"> self.assert_(u is not u2) </span><span class="cx"> </span><ins>+ def testrefresh(self): + m = mapper(User, users) + u = m.get(7) + u.user_name = 'foo' + objectstore.refresh(u) + + # its refreshed, so not dirty + self.assert_(u not in objectstore.get_session().uow.dirty) + + # username is back to the DB + self.assert_(u.user_name == 'jack') + + u.user_name = 'foo' + # now its dirty + self.assert_(u in objectstore.get_session().uow.dirty) + self.assert_(u.user_name == 'foo') + objectstore.expire(u) + + # expired, but not refreshed yet. still dirty + self.assert_(u in objectstore.get_session().uow.dirty) + # get the attribute, it refreshes + self.assert_(u.user_name == 'jack') + # not dirty anymore + self.assert_(u not in objectstore.get_session().uow.dirty) + </ins><span class="cx"> def testmagic(self): </span><span class="cx"> m = mapper(User, users, properties = { </span><span class="cx"> 'addresses' : relation(mapper(Address, addresses)) </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-10 04:47:47
|
<!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>[1125] sqlalchemy/trunk/lib/sqlalchemy: utf-8 encoding is switchable at the engine level, ticket [ticket:101]</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1125</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 22:47:38 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>utf-8 encoding is switchable at the engine level, ticket [ticket:101]</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunkdocbuildcontentdbenginemyt">sqlalchemy/trunk/doc/build/content/dbengine.myt</a></li> <li><a href="#sqlalchemytrunklibsqlalchemyenginepy">sqlalchemy/trunk/lib/sqlalchemy/engine.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemytypespy">sqlalchemy/trunk/lib/sqlalchemy/types.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunkdocbuildcontentdbenginemyt"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/doc/build/content/dbengine.myt (1124 => 1125)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/doc/build/content/dbengine.myt 2006-03-10 04:35:34 UTC (rev 1124) +++ sqlalchemy/trunk/doc/build/content/dbengine.myt 2006-03-10 04:47:38 UTC (rev 1125) </span><span class="lines">@@ -103,6 +103,7 @@ </span><span class="cx"> <li>use_ansi=True : used only by Oracle; when False, the Oracle driver attempts to support a particular "quirk" of some Oracle databases, that the LEFT OUTER JOIN SQL syntax is not supported, and the "Oracle join" syntax of using <% "<column1>(+)=<column2>" |h%> must be used in order to achieve a LEFT OUTER JOIN. Its advised that the Oracle database be configured to have full ANSI support instead of using this feature.</li> </span><span class="cx"> <li>use_oids=False : used only by Postgres, will enable the column name "oid" as the object ID column. Postgres as of 8.1 has object IDs disabled by default.</li> </span><span class="cx"> <li>convert_unicode=False : if set to True, all String/character based types will convert Unicode values to raw byte values going into the database, and all raw byte values to Python Unicode coming out in result sets. This is an engine-wide method to provide unicode across the board. For unicode conversion on a column-by-column level, use the Unicode column type instead.</li> </span><ins>+ <li>encoding='utf-8' : the encoding to use when doing unicode translations.</li> </ins><span class="cx"> </ul> </span><span class="cx"> </&> </span><span class="cx"> <&|doclib.myt:item, name="proxy", description="Using the Proxy Engine" &> </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemyenginepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/engine.py (1124 => 1125)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/engine.py 2006-03-10 04:35:34 UTC (rev 1124) +++ sqlalchemy/trunk/lib/sqlalchemy/engine.py 2006-03-10 04:47:38 UTC (rev 1125) </span><span class="lines">@@ -180,7 +180,7 @@ </span><span class="cx"> SQLEngines are constructed via the create_engine() function inside this package. </span><span class="cx"> """ </span><span class="cx"> </span><del>- def __init__(self, pool=None, echo=False, logger=None, default_ordering=False, echo_pool=False, echo_uow=False, convert_unicode=False, **params): </del><ins>+ def __init__(self, pool=None, echo=False, logger=None, default_ordering=False, echo_pool=False, echo_uow=False, convert_unicode=False, encoding='utf-8', **params): </ins><span class="cx"> """constructs a new SQLEngine. SQLEngines should be constructed via the create_engine() </span><span class="cx"> function which will construct the appropriate subclass of SQLEngine.""" </span><span class="cx"> # get a handle on the connection pool via the connect arguments </span><span class="lines">@@ -197,6 +197,7 @@ </span><span class="cx"> self.echo = echo </span><span class="cx"> self.echo_uow = echo_uow </span><span class="cx"> self.convert_unicode = convert_unicode </span><ins>+ self.encoding = encoding </ins><span class="cx"> self.context = util.ThreadLocal(raiseerror=False) </span><span class="cx"> self._ischema = None </span><span class="cx"> self._figure_paramstyle() </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemytypespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/types.py (1124 => 1125)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/types.py 2006-03-10 04:35:34 UTC (rev 1124) +++ sqlalchemy/trunk/lib/sqlalchemy/types.py 2006-03-10 04:47:38 UTC (rev 1125) </span><span class="lines">@@ -77,12 +77,12 @@ </span><span class="cx"> if not engine.convert_unicode or value is None or not isinstance(value, unicode): </span><span class="cx"> return value </span><span class="cx"> else: </span><del>- return value.encode('utf-8') </del><ins>+ return value.encode(engine.encoding) </ins><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> if not engine.convert_unicode or value is None or isinstance(value, unicode): </span><span class="cx"> return value </span><span class="cx"> else: </span><del>- return value.decode('utf-8') </del><ins>+ return value.decode(engine.encoding) </ins><span class="cx"> def adapt_args(self): </span><span class="cx"> if self.length is None: </span><span class="cx"> return TEXT() </span><span class="lines">@@ -92,12 +92,12 @@ </span><span class="cx"> class Unicode(String): </span><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> if isinstance(value, unicode): </span><del>- return value.encode('utf-8') </del><ins>+ return value.encode(engine.encoding) </ins><span class="cx"> else: </span><span class="cx"> return value </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> if not isinstance(value, unicode): </span><del>- return value.decode('utf-8') </del><ins>+ return value.decode(engine.encoding) </ins><span class="cx"> else: </span><span class="cx"> return value </span><span class="cx"> </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-10 04:35:43
|
<!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>[1124] sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py: committed patch for MSDouble/tinyint from [ticket:106]</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1124</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 22:35:34 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>committed patch for MSDouble/tinyint from [ticket:106]</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemydatabasesmysqlpy">sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemydatabasesmysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py (1123 => 1124)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py 2006-03-10 04:26:35 UTC (rev 1123) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py 2006-03-10 04:35:34 UTC (rev 1124) </span><span class="lines">@@ -13,6 +13,7 @@ </span><span class="cx"> import sqlalchemy.types as sqltypes </span><span class="cx"> from sqlalchemy import * </span><span class="cx"> import sqlalchemy.databases.information_schema as ischema </span><ins>+from sqlalchemy.exceptions import * </ins><span class="cx"> </span><span class="cx"> try: </span><span class="cx"> import MySQLdb as mysql </span><span class="lines">@@ -22,9 +23,24 @@ </span><span class="cx"> class MSNumeric(sqltypes.Numeric): </span><span class="cx"> def get_col_spec(self): </span><span class="cx"> return "NUMERIC(%(precision)s, %(length)s)" % {'precision': self.precision, 'length' : self.length} </span><ins>+class MSDouble(sqltypes.Numeric): + def __init__(self, precision = None, length = None): + if (precision is None and length is not None) or (precision is not None and length is None): + raise ArgumentError("You must specify both precision and length or omit both altogether.") + super(MSDouble, self).__init__(precision, length) + def get_col_spec(self): + if self.precision is not None and self.length is not None: + return "DOUBLE(%(precision)s, %(length)s)" % {'precision': self.precision, 'length' : self.length} + else: + return "DOUBLE" </ins><span class="cx"> class MSFloat(sqltypes.Float): </span><ins>+ def __init__(self, precision = None): + super(MSFloat, self).__init__(precision) </ins><span class="cx"> def get_col_spec(self): </span><del>- return "FLOAT(%(precision)s)" % {'precision': self.precision} </del><ins>+ if self.precision is not None: + return "FLOAT(%(precision)s)" % {'precision': self.precision} + else: + return "FLOAT" </ins><span class="cx"> class MSInteger(sqltypes.Integer): </span><span class="cx"> def get_col_spec(self): </span><span class="cx"> return "INTEGER" </span><span class="lines">@@ -86,11 +102,13 @@ </span><span class="cx"> ischema_names = { </span><span class="cx"> 'int' : MSInteger, </span><span class="cx"> 'smallint' : MSSmallInteger, </span><ins>+ 'tinyint' : MSSmallInteger, </ins><span class="cx"> 'varchar' : MSString, </span><span class="cx"> 'char' : MSChar, </span><span class="cx"> 'text' : MSText, </span><span class="cx"> 'decimal' : MSNumeric, </span><span class="cx"> 'float' : MSFloat, </span><ins>+ 'double' : MSDouble, </ins><span class="cx"> 'timestamp' : MSDateTime, </span><span class="cx"> 'datetime' : MSDateTime, </span><span class="cx"> 'date' : MSDate, </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-10 04:26:43
|
<!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>[1123] sqlalchemy/trunk/lib/sqlalchemy/attributes.py: added exception import</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1123</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 22:26:35 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>added exception import</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemyattributespy">sqlalchemy/trunk/lib/sqlalchemy/attributes.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemyattributespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/attributes.py (1122 => 1123)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/attributes.py 2006-03-10 04:22:59 UTC (rev 1122) +++ sqlalchemy/trunk/lib/sqlalchemy/attributes.py 2006-03-10 04:26:35 UTC (rev 1123) </span><span class="lines">@@ -28,6 +28,7 @@ </span><span class="cx"> """ </span><span class="cx"> </span><span class="cx"> import util </span><ins>+from exceptions import * </ins><span class="cx"> </span><span class="cx"> class SmartProperty(object): </span><span class="cx"> """Provides a property object that will communicate set/get/delete operations </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-10 04:23:11
|
<!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>[1122] sqlalchemy/trunk/lib/sqlalchemy/util.py: HistoryArrayList checks internal list as a list or dict to clear it</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1122</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 22:22:59 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>HistoryArrayList checks internal list as a list or dict to clear it</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemyutilpy">sqlalchemy/trunk/lib/sqlalchemy/util.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemyutilpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/util.py (1121 => 1122)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/util.py 2006-03-09 18:30:27 UTC (rev 1121) +++ sqlalchemy/trunk/lib/sqlalchemy/util.py 2006-03-10 04:22:59 UTC (rev 1122) </span><span class="lines">@@ -365,14 +365,19 @@ </span><span class="cx"> for key, status in self.records.iteritems(): </span><span class="cx"> if status is False or status is None: </span><span class="cx"> list.append(key) </span><del>- self.data[:] = [] </del><ins>+ self._clear_data() </ins><span class="cx"> self.records = {} </span><span class="cx"> for l in list: </span><span class="cx"> self.append_nohistory(l) </span><span class="cx"> def clear(self): </span><span class="cx"> """clears the list and removes all history.""" </span><del>- self.data[:] = [] </del><ins>+ self._clear_data() </ins><span class="cx"> self.records = {} </span><ins>+ def _clear_data(self): + if isinstance(self.data, dict): + self.data.clear() + else: + self.data[:] = [] </ins><span class="cx"> def added_items(self): </span><span class="cx"> """returns a list of items that have been added since the last "committed" state.""" </span><span class="cx"> return [key for key in self.data if self.records[key] is True] </span></span></pre> </div> </div> </body> </html> |
<!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>[1121] sqlalchemy/trunk/test: overhaul to types system, decoupled base type and engine-specific type into a composed pattern instead of goofy inheritance....gets rid of TypeDecorator (now a no-op) and enables all inhertance</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1121</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 12:30:27 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>overhaul to types system, decoupled base type and engine-specific type into a composed pattern instead of goofy inheritance....gets rid of TypeDecorator (now a no-op) and enables all inhertance</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemytypespy">sqlalchemy/trunk/lib/sqlalchemy/types.py</a></li> <li><a href="#sqlalchemytrunktesttesttypespy">sqlalchemy/trunk/test/testtypes.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemytypespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/types.py (1120 => 1121)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/types.py 2006-03-09 18:22:32 UTC (rev 1120) +++ sqlalchemy/trunk/lib/sqlalchemy/types.py 2006-03-09 18:30:27 UTC (rev 1121) </span><span class="lines">@@ -14,52 +14,48 @@ </span><span class="cx"> import sqlalchemy.util as util </span><span class="cx"> </span><span class="cx"> class TypeEngine(object): </span><ins>+ basetypes = [] + def __init__(self, *args, **kwargs): + pass + def _get_impl(self): + if hasattr(self, '_impl'): + return self._impl + else: + return NULLTYPE + def _set_impl(self, impl): + self._impl = impl + impl = property(_get_impl, _set_impl) </ins><span class="cx"> def get_col_spec(self): </span><del>- raise NotImplementedError() </del><ins>+ return self.impl.get_col_spec() </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><del>- raise NotImplementedError() </del><ins>+ return self.impl.convert_bind_param(value, engine) </ins><span class="cx"> def convert_result_value(self, value, engine): </span><del>- raise NotImplementedError() - def adapt(self, typeobj): - """given a class that is a subclass of this TypeEngine's class, produces a new - instance of that class with an equivalent state to this TypeEngine. The given - class is a database-specific subclass which is obtained via a lookup dictionary, - mapped against the class returned by the class_to_adapt() method.""" - return typeobj() </del><ins>+ return self.impl.convert_result_value(value, engine) + def set_impl(self, impltype): + self.impl = impltype(**self.get_constructor_args()) + def get_constructor_args(self): + return {} </ins><span class="cx"> def adapt_args(self): </span><del>- """Returns an instance of this TypeEngine instance's class, adapted according - to the constructor arguments of this TypeEngine. Default return value is - just this object instance.""" </del><span class="cx"> return self </span><del>- def class_to_adapt(self): - """returns the class that should be sent to the adapt() method. This class - will be used to lookup an approprate database-specific subclass.""" - return self.__class__ -# def __repr__(self): - # return util.generic_repr(self) - </del><ins>+ </ins><span class="cx"> def adapt_type(typeobj, colspecs): </span><del>- """given a generic type from this package, and a dictionary of - "conversion" specs from a DB-specific package, adapts the type - to a correctly-configured type instance from the DB-specific package.""" - if type(typeobj) is type: </del><ins>+ if isinstance(typeobj, type): </ins><span class="cx"> typeobj = typeobj() </span><del>- # if the type is not a base type, i.e. not from our module, or its Null, - # we return the type as is - if (typeobj.__module__ != 'sqlalchemy.types' or typeobj.__class__ is NullTypeEngine) and not isinstance(typeobj, TypeDecorator): - return typeobj - typeobj = typeobj.adapt_args() - t = typeobj.class_to_adapt() - for t in t.__mro__[0:-1]: </del><ins>+ t2 = typeobj.adapt_args() + for t in t2.__class__.__mro__[0:-1]: </ins><span class="cx"> try: </span><del>- return typeobj.adapt(colspecs[t]) - except KeyError, e: </del><ins>+ impltype = colspecs[t] + break + except KeyError: </ins><span class="cx"> pass </span><del>- return typeobj.adapt(typeobj.__class__) </del><ins>+ else: + # couldnt adapt...raise exception ? + return typeobj + typeobj.set_impl(impltype) + typeobj.impl.impl = NULLTYPE + return typeobj </ins><span class="cx"> </span><span class="cx"> class NullTypeEngine(TypeEngine): </span><del>- def __init__(self, *args, **kwargs): - pass </del><span class="cx"> def get_col_spec(self): </span><span class="cx"> raise NotImplementedError() </span><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="lines">@@ -68,32 +64,15 @@ </span><span class="cx"> return value </span><span class="cx"> </span><span class="cx"> class TypeDecorator(object): </span><del>- def get_col_spec(self): - return self.extended.get_col_spec() - def adapt(self, typeobj): - if self.extended is self: - t = self.__class__.__mro__[2] - self.extended = t.adapt(self, typeobj) - else: - self.extended = self.extended.adapt(typeobj) - return self - def adapt_args(self): - t = self.__class__.__mro__[2] - self.extended = t.adapt_args(self) - return self - def class_to_adapt(self): - return self.extended.__class__ </del><ins>+ """TypeDecorator is deprecated""" + pass </ins><span class="cx"> </span><del>-class String(NullTypeEngine): </del><ins>+ +class String(TypeEngine): </ins><span class="cx"> def __init__(self, length = None): </span><span class="cx"> self.length = length </span><del>- def adapt(self, typeobj): - return typeobj(self.length) - def adapt_args(self): - if self.length is None: - return TEXT() - else: - return self </del><ins>+ def get_constructor_args(self): + return {'length':self.length} </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> if not engine.convert_unicode or value is None or not isinstance(value, unicode): </span><span class="cx"> return value </span><span class="lines">@@ -104,10 +83,13 @@ </span><span class="cx"> return value </span><span class="cx"> else: </span><span class="cx"> return value.decode('utf-8') </span><del>- -class Unicode(TypeDecorator,String): - def __init__(self, length=None): - String.__init__(self, length) </del><ins>+ def adapt_args(self): + if self.length is None: + return TEXT() + else: + return self + +class Unicode(String): </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> if isinstance(value, unicode): </span><span class="cx"> return value.encode('utf-8') </span><span class="lines">@@ -119,49 +101,48 @@ </span><span class="cx"> else: </span><span class="cx"> return value </span><span class="cx"> </span><del>-class Integer(NullTypeEngine): </del><ins>+class Integer(TypeEngine): </ins><span class="cx"> """integer datatype""" </span><del>- # TODO: do string bind params need int(value) performed before sending ? - # seems to be not needed with SQLite, Postgres </del><span class="cx"> pass </span><del>- -class Smallinteger(Integer): </del><ins>+ +class SmallInteger(Integer): </ins><span class="cx"> """ smallint datatype """ </span><span class="cx"> pass </span><del>- -class Numeric(NullTypeEngine): </del><ins>+Smallinteger = SmallInteger + +class Numeric(TypeEngine): </ins><span class="cx"> def __init__(self, precision = 10, length = 2): </span><span class="cx"> self.precision = precision </span><span class="cx"> self.length = length </span><del>- def adapt(self, typeobj): - return typeobj(self.precision, self.length) </del><ins>+ def get_constructor_args(self): + return {'precision':self.precision, 'length':self.length} </ins><span class="cx"> </span><del>-class Float(NullTypeEngine): </del><ins>+class Float(TypeEngine): </ins><span class="cx"> def __init__(self, precision = 10): </span><span class="cx"> self.precision = precision </span><del>- def adapt(self, typeobj): - return typeobj(self.precision) </del><ins>+ def get_constructor_args(self): + return {'precision':self.precision} </ins><span class="cx"> </span><del>-class DateTime(NullTypeEngine): </del><ins>+class DateTime(TypeEngine): </ins><span class="cx"> pass </span><span class="cx"> </span><del>-class Date(NullTypeEngine): </del><ins>+class Date(TypeEngine): </ins><span class="cx"> pass </span><span class="cx"> </span><del>-class Time(NullTypeEngine): </del><ins>+class Time(TypeEngine): </ins><span class="cx"> pass </span><span class="cx"> </span><del>-class Binary(NullTypeEngine): </del><ins>+class Binary(TypeEngine): </ins><span class="cx"> def __init__(self, length=None): </span><span class="cx"> self.length = length </span><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> return engine.dbapi().Binary(value) </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> return value </span><del>- def adapt(self, typeobj): - return typeobj(self.length) </del><ins>+ def get_constructor_args(self): + return {'length':self.length} </ins><span class="cx"> </span><del>-class Boolean(NullTypeEngine): </del><ins>+class Boolean(TypeEngine): </ins><span class="cx"> pass </span><span class="cx"> </span><span class="cx"> class FLOAT(Float):pass </span></span></pre></div> <a id="sqlalchemytrunktesttesttypespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/testtypes.py (1120 => 1121)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/testtypes.py 2006-03-09 18:22:32 UTC (rev 1120) +++ sqlalchemy/trunk/test/testtypes.py 2006-03-09 18:30:27 UTC (rev 1121) </span><span class="lines">@@ -17,25 +17,31 @@ </span><span class="cx"> def adapt_args(self): </span><span class="cx"> return self </span><span class="cx"> </span><del>-class MyDecoratedType(types.TypeDecorator, types.String): </del><ins>+class MyDecoratedType(types.String): </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> return "BIND_IN"+ value </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> return value + "BIND_OUT" </span><span class="cx"> </span><ins>+class MyUnicodeType(types.Unicode): + def convert_bind_param(self, value, engine): + return "UNI_BIND_IN"+ value + def convert_result_value(self, value, engine): + return value + "UNI_BIND_OUT" + </ins><span class="cx"> class OverrideTest(PersistTest): </span><span class="cx"> """tests user-defined types, including a full type as well as a TypeDecorator""" </span><span class="cx"> </span><span class="cx"> def testprocessing(self): </span><span class="cx"> </span><span class="cx"> global users </span><del>- users.insert().execute(user_id = 2, goofy = 'jack', goofy2='jack', goofy3='jack') - users.insert().execute(user_id = 3, goofy = 'lala', goofy2='lala', goofy3='lala') - users.insert().execute(user_id = 4, goofy = 'fred', goofy2='fred', goofy3='fred') </del><ins>+ users.insert().execute(user_id = 2, goofy = 'jack', goofy2='jack', goofy3='jack', goofy4='jack') + users.insert().execute(user_id = 3, goofy = 'lala', goofy2='lala', goofy3='lala', goofy4='lala') + users.insert().execute(user_id = 4, goofy = 'fred', goofy2='fred', goofy3='fred', goofy4='fred') </ins><span class="cx"> </span><span class="cx"> l = users.select().execute().fetchall() </span><span class="cx"> print repr(l) </span><del>- self.assert_(l == [(2, 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT'), (3, 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT'), (4, 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT')]) </del><ins>+ self.assert_(l == [(2, 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT', u'UNI_BIND_INjackUNI_BIND_OUT'), (3, 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT', u'UNI_BIND_INlalaUNI_BIND_OUT'), (4, 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT', u'UNI_BIND_INfredUNI_BIND_OUT')]) </ins><span class="cx"> </span><span class="cx"> def setUpAll(self): </span><span class="cx"> global users </span><span class="lines">@@ -49,6 +55,9 @@ </span><span class="cx"> </span><span class="cx"> # decorated type without an argument, it will adapt_args to TEXT </span><span class="cx"> Column('goofy3', MyDecoratedType, nullable = False), </span><ins>+ + Column('goofy4', MyUnicodeType, nullable = False), + </ins><span class="cx"> ) </span><span class="cx"> </span><span class="cx"> users.create() </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-09 18:22:42
|
<!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>[1120] sqlalchemy/branches/new_types/test: overhaul to types to work in a more simple fashion</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1120</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 12:22:32 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>overhaul to types to work in a more simple fashion</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemybranchesnew_typeslibsqlalchemytypespy">sqlalchemy/branches/new_types/lib/sqlalchemy/types.py</a></li> <li><a href="#sqlalchemybranchesnew_typestesttesttypespy">sqlalchemy/branches/new_types/test/testtypes.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemybranchesnew_typeslibsqlalchemytypespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/new_types/lib/sqlalchemy/types.py (1119 => 1120)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/new_types/lib/sqlalchemy/types.py 2006-03-09 16:39:31 UTC (rev 1119) +++ sqlalchemy/branches/new_types/lib/sqlalchemy/types.py 2006-03-09 18:22:32 UTC (rev 1120) </span><span class="lines">@@ -14,52 +14,46 @@ </span><span class="cx"> import sqlalchemy.util as util </span><span class="cx"> </span><span class="cx"> class TypeEngine(object): </span><ins>+ basetypes = [] + def _get_impl(self): + if hasattr(self, '_impl'): + return self._impl + else: + return NULLTYPE + def _set_impl(self, impl): + self._impl = impl + impl = property(_get_impl, _set_impl) </ins><span class="cx"> def get_col_spec(self): </span><del>- raise NotImplementedError() </del><ins>+ return self.impl.get_col_spec() </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><del>- raise NotImplementedError() </del><ins>+ return self.impl.convert_bind_param(value, engine) </ins><span class="cx"> def convert_result_value(self, value, engine): </span><del>- raise NotImplementedError() - def adapt(self, typeobj): - """given a class that is a subclass of this TypeEngine's class, produces a new - instance of that class with an equivalent state to this TypeEngine. The given - class is a database-specific subclass which is obtained via a lookup dictionary, - mapped against the class returned by the class_to_adapt() method.""" - return typeobj() </del><ins>+ return self.impl.convert_result_value(value, engine) + def set_impl(self, impltype): + self.impl = impltype(**self.get_constructor_args()) + def get_constructor_args(self): + return {} </ins><span class="cx"> def adapt_args(self): </span><del>- """Returns an instance of this TypeEngine instance's class, adapted according - to the constructor arguments of this TypeEngine. Default return value is - just this object instance.""" </del><span class="cx"> return self </span><del>- def class_to_adapt(self): - """returns the class that should be sent to the adapt() method. This class - will be used to lookup an approprate database-specific subclass.""" - return self.__class__ -# def __repr__(self): - # return util.generic_repr(self) - </del><ins>+ </ins><span class="cx"> def adapt_type(typeobj, colspecs): </span><del>- """given a generic type from this package, and a dictionary of - "conversion" specs from a DB-specific package, adapts the type - to a correctly-configured type instance from the DB-specific package.""" - if type(typeobj) is type: </del><ins>+ if isinstance(typeobj, type): </ins><span class="cx"> typeobj = typeobj() </span><del>- # if the type is not a base type, i.e. not from our module, or its Null, - # we return the type as is - if (typeobj.__module__ != 'sqlalchemy.types' or typeobj.__class__ is NullTypeEngine) and not isinstance(typeobj, TypeDecorator): - return typeobj - typeobj = typeobj.adapt_args() - t = typeobj.class_to_adapt() - for t in t.__mro__[0:-1]: </del><ins>+ t2 = typeobj.adapt_args() + for t in t2.__class__.__mro__[0:-1]: </ins><span class="cx"> try: </span><del>- return typeobj.adapt(colspecs[t]) - except KeyError, e: </del><ins>+ impltype = colspecs[t] + break + except KeyError: </ins><span class="cx"> pass </span><del>- return typeobj.adapt(typeobj.__class__) </del><ins>+ else: + # couldnt adapt...raise exception ? + return typeobj + typeobj.set_impl(impltype) + typeobj.impl.impl = NULLTYPE + return typeobj </ins><span class="cx"> </span><span class="cx"> class NullTypeEngine(TypeEngine): </span><del>- def __init__(self, *args, **kwargs): - pass </del><span class="cx"> def get_col_spec(self): </span><span class="cx"> raise NotImplementedError() </span><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="lines">@@ -68,32 +62,15 @@ </span><span class="cx"> return value </span><span class="cx"> </span><span class="cx"> class TypeDecorator(object): </span><del>- def get_col_spec(self): - return self.extended.get_col_spec() - def adapt(self, typeobj): - if self.extended is self: - t = self.__class__.__mro__[2] - self.extended = t.adapt(self, typeobj) - else: - self.extended = self.extended.adapt(typeobj) - return self - def adapt_args(self): - t = self.__class__.__mro__[2] - self.extended = t.adapt_args(self) - return self - def class_to_adapt(self): - return self.extended.__class__ </del><ins>+ """TypeDecorator is deprecated""" + pass </ins><span class="cx"> </span><del>-class String(NullTypeEngine): </del><ins>+ +class String(TypeEngine): </ins><span class="cx"> def __init__(self, length = None): </span><span class="cx"> self.length = length </span><del>- def adapt(self, typeobj): - return typeobj(self.length) - def adapt_args(self): - if self.length is None: - return TEXT() - else: - return self </del><ins>+ def get_constructor_args(self): + return {'length':self.length} </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> if not engine.convert_unicode or value is None or not isinstance(value, unicode): </span><span class="cx"> return value </span><span class="lines">@@ -104,10 +81,13 @@ </span><span class="cx"> return value </span><span class="cx"> else: </span><span class="cx"> return value.decode('utf-8') </span><del>- -class Unicode(TypeDecorator,String): - def __init__(self, length=None): - String.__init__(self, length) </del><ins>+ def adapt_args(self): + if self.length is None: + return TEXT() + else: + return self + +class Unicode(String): </ins><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> if isinstance(value, unicode): </span><span class="cx"> return value.encode('utf-8') </span><span class="lines">@@ -119,49 +99,48 @@ </span><span class="cx"> else: </span><span class="cx"> return value </span><span class="cx"> </span><del>-class Integer(NullTypeEngine): </del><ins>+class Integer(TypeEngine): </ins><span class="cx"> """integer datatype""" </span><del>- # TODO: do string bind params need int(value) performed before sending ? - # seems to be not needed with SQLite, Postgres </del><span class="cx"> pass </span><del>- -class Smallinteger(Integer): </del><ins>+ +class SmallInteger(Integer): </ins><span class="cx"> """ smallint datatype """ </span><span class="cx"> pass </span><del>- -class Numeric(NullTypeEngine): </del><ins>+Smallinteger = SmallInteger + +class Numeric(TypeEngine): </ins><span class="cx"> def __init__(self, precision = 10, length = 2): </span><span class="cx"> self.precision = precision </span><span class="cx"> self.length = length </span><del>- def adapt(self, typeobj): - return typeobj(self.precision, self.length) </del><ins>+ def get_constructor_args(self): + return {'precision':self.precision, 'length':self.length} </ins><span class="cx"> </span><del>-class Float(NullTypeEngine): </del><ins>+class Float(TypeEngine): </ins><span class="cx"> def __init__(self, precision = 10): </span><span class="cx"> self.precision = precision </span><del>- def adapt(self, typeobj): - return typeobj(self.precision) </del><ins>+ def get_constructor_args(self): + return {'precision':self.precision} </ins><span class="cx"> </span><del>-class DateTime(NullTypeEngine): </del><ins>+class DateTime(TypeEngine): </ins><span class="cx"> pass </span><span class="cx"> </span><del>-class Date(NullTypeEngine): </del><ins>+class Date(TypeEngine): </ins><span class="cx"> pass </span><span class="cx"> </span><del>-class Time(NullTypeEngine): </del><ins>+class Time(TypeEngine): </ins><span class="cx"> pass </span><span class="cx"> </span><del>-class Binary(NullTypeEngine): </del><ins>+class Binary(TypeEngine): </ins><span class="cx"> def __init__(self, length=None): </span><span class="cx"> self.length = length </span><span class="cx"> def convert_bind_param(self, value, engine): </span><span class="cx"> return engine.dbapi().Binary(value) </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> return value </span><del>- def adapt(self, typeobj): - return typeobj(self.length) </del><ins>+ def get_constructor_args(self): + return {'length':self.length} </ins><span class="cx"> </span><del>-class Boolean(NullTypeEngine): </del><ins>+class Boolean(TypeEngine): </ins><span class="cx"> pass </span><span class="cx"> </span><span class="cx"> class FLOAT(Float):pass </span></span></pre></div> <a id="sqlalchemybranchesnew_typestesttesttypespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/new_types/test/testtypes.py (1119 => 1120)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/new_types/test/testtypes.py 2006-03-09 16:39:31 UTC (rev 1119) +++ sqlalchemy/branches/new_types/test/testtypes.py 2006-03-09 18:22:32 UTC (rev 1120) </span><span class="lines">@@ -23,19 +23,25 @@ </span><span class="cx"> def convert_result_value(self, value, engine): </span><span class="cx"> return value + "BIND_OUT" </span><span class="cx"> </span><ins>+class MyUnicodeType(types.Unicode): + def convert_bind_param(self, value, engine): + return "UNI_BIND_IN"+ value + def convert_result_value(self, value, engine): + return value + "UNI_BIND_OUT" + </ins><span class="cx"> class OverrideTest(PersistTest): </span><span class="cx"> """tests user-defined types, including a full type as well as a TypeDecorator""" </span><span class="cx"> </span><span class="cx"> def testprocessing(self): </span><span class="cx"> </span><span class="cx"> global users </span><del>- users.insert().execute(user_id = 2, goofy = 'jack', goofy2='jack', goofy3='jack') - users.insert().execute(user_id = 3, goofy = 'lala', goofy2='lala', goofy3='lala') - users.insert().execute(user_id = 4, goofy = 'fred', goofy2='fred', goofy3='fred') </del><ins>+ users.insert().execute(user_id = 2, goofy = 'jack', goofy2='jack', goofy3='jack', goofy4='jack') + users.insert().execute(user_id = 3, goofy = 'lala', goofy2='lala', goofy3='lala', goofy4='lala') + users.insert().execute(user_id = 4, goofy = 'fred', goofy2='fred', goofy3='fred', goofy4='fred') </ins><span class="cx"> </span><span class="cx"> l = users.select().execute().fetchall() </span><span class="cx"> print repr(l) </span><del>- self.assert_(l == [(2, 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT'), (3, 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT'), (4, 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT')]) </del><ins>+ self.assert_(l == [(2, 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT', u'UNI_BIND_INjackUNI_BIND_OUT'), (3, 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT', u'UNI_BIND_INlalaUNI_BIND_OUT'), (4, 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT', u'UNI_BIND_INfredUNI_BIND_OUT')]) </ins><span class="cx"> </span><span class="cx"> def setUpAll(self): </span><span class="cx"> global users </span><span class="lines">@@ -49,6 +55,9 @@ </span><span class="cx"> </span><span class="cx"> # decorated type without an argument, it will adapt_args to TEXT </span><span class="cx"> Column('goofy3', MyDecoratedType, nullable = False), </span><ins>+ + Column('goofy4', MyUnicodeType, nullable = False), + </ins><span class="cx"> ) </span><span class="cx"> </span><span class="cx"> users.create() </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-09 16:39:43
|
<!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>[1119] sqlalchemy/branches/new_types/: branch for reworking the types</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1119</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 10:39:31 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>branch for reworking the types</pre> <h3>Added Paths</h3> <ul> <li>sqlalchemy/branches/new_types/</li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemybranchesnew_typesfromrev1118sqlalchemytrunk"></a> <div class="copfile"><h4>Copied: sqlalchemy/branches/new_types (from rev 1118, sqlalchemy/trunk) ( => )</h4> <pre class="diff"><span> <span class="info"> </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-09 15:54:53
|
<!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>[1118] sqlalchemy/trunk/doc/build/content/datamapping.myt: fixed assocaition example</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1118</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-09 09:54:44 -0600 (Thu, 09 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>fixed assocaition example</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunkdocbuildcontentdatamappingmyt">sqlalchemy/trunk/doc/build/content/datamapping.myt</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunkdocbuildcontentdatamappingmyt"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/doc/build/content/datamapping.myt (1117 => 1118)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/doc/build/content/datamapping.myt 2006-03-09 00:24:15 UTC (rev 1117) +++ sqlalchemy/trunk/doc/build/content/datamapping.myt 2006-03-09 15:54:44 UTC (rev 1118) </span><span class="lines">@@ -734,26 +734,25 @@ </span><span class="cx"> pass </span><span class="cx"> </span><span class="cx"> # mapper for KeywordAssociation </span><del>- KeywordAssociation.mapper = mapper(KeywordAssociation, itemkeywords) - - # mappers for Users, Keywords - User.mapper = mapper(User, users) - Keyword.mapper = mapper(Keyword, keywords) - - # define the mapper. when we load an article, we always want to get the keywords via - # eager loading. but the user who added each keyword, we usually dont need so specify - # lazy loading for that. - m = mapper(Article, articles, properties=dict( - keywords = relation(KeywordAssociation.mapper, lazy=False, association=Keyword, </del><ins>+ # specify "primary key" columns manually + KeywordAssociation.mapper = mapper(KeywordAssociation, itemkeywords, </ins><span class="cx"> primary_key = [itemkeywords.c.article_id, itemkeywords.c.keyword_id], </span><span class="cx"> properties={ </span><span class="cx"> 'keyword' : relation(Keyword, lazy = False), # uses primary Keyword mapper </span><span class="cx"> 'user' : relation(User, lazy = True) # uses primary User mapper </span><span class="cx"> } </span><del>- ) - ) </del><span class="cx"> ) </span><span class="cx"> </span><ins>+ # mappers for Users, Keywords + User.mapper = mapper(User, users) + Keyword.mapper = mapper(Keyword, keywords) + + # define the mapper. + m = mapper(Article, articles, properties={ + 'keywords':relation(KeywordAssociation.mapper, lazy=False, association=Keyword) + } + ) + </ins><span class="cx"> # bonus step - well, we do want to load the users in one shot, </span><span class="cx"> # so modify the mapper via an option. </span><span class="cx"> # this returns a new mapper with the option switched on. </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-09 00:24:27
|
<!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>[1117] sqlalchemy/trunk: added 'noninherited table' prop to mapper indicating the "lead" table, in the case of</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1117</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-08 18:24:15 -0600 (Wed, 08 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>added 'noninherited table' prop to mapper indicating the "lead" table, in the case of inheritance. relations now create priamry/secondary joins against that lead table. if you want to create it against an inherited table, use explicit join conditions. added 'correlate' argument to CompoundSelect to get polymorph example working again.</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunkCHANGES">sqlalchemy/trunk/CHANGES</a></li> <li><a href="#sqlalchemytrunkexamplespolymorphpolymorphpy">sqlalchemy/trunk/examples/polymorph/polymorph.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemymappingmapperpy">sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemymappingpropertiespy">sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemysqlpy">sqlalchemy/trunk/lib/sqlalchemy/sql.py</a></li> <li><a href="#sqlalchemytrunktestinheritancepy">sqlalchemy/trunk/test/inheritance.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunkCHANGES"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/CHANGES (1116 => 1117)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/CHANGES 2006-03-08 22:32:55 UTC (rev 1116) +++ sqlalchemy/trunk/CHANGES 2006-03-09 00:24:15 UTC (rev 1117) </span><span class="lines">@@ -1,3 +1,5 @@ </span><ins>+0.1.4 + </ins><span class="cx"> 0.1.3 </span><span class="cx"> - completed "post_update" feature, will add a second update statement before inserts </span><span class="cx"> and after deletes in order to reconcile a relationship without any dependencies </span></span></pre></div> <a id="sqlalchemytrunkexamplespolymorphpolymorphpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/examples/polymorph/polymorph.py (1116 => 1117)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/examples/polymorph/polymorph.py 2006-03-08 22:32:55 UTC (rev 1116) +++ sqlalchemy/trunk/examples/polymorph/polymorph.py 2006-03-09 00:24:15 UTC (rev 1117) </span><span class="lines">@@ -6,8 +6,8 @@ </span><span class="cx"> # extend from a common base class, although this same approach can be used </span><span class="cx"> # with </span><span class="cx"> </span><del>-#db = create_engine('sqlite://', echo=True, echo_uow=False) -db = create_engine('postgres://user=scott&password=tiger&host=127.0.0.1&database=test', echo=True, echo_uow=False) </del><ins>+db = create_engine('sqlite://', echo=True, echo_uow=False) +#db = create_engine('postgres://user=scott&password=tiger&host=127.0.0.1&database=test', echo=True, echo_uow=False) </ins><span class="cx"> </span><span class="cx"> # a table to store companies </span><span class="cx"> companies = Table('companies', db, </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemymappingmapperpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py (1116 => 1117)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-08 22:32:55 UTC (rev 1116) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-09 00:24:15 UTC (rev 1117) </span><span class="lines">@@ -68,8 +68,10 @@ </span><span class="cx"> self._synchronizer = sync.ClauseSynchronizer(self, self, sync.ONETOMANY) </span><span class="cx"> self._synchronizer.compile(self.table.onclause, inherits.tables, TableFinder(table)) </span><span class="cx"> self.inherits = inherits </span><ins>+ self.noninherited_table = table </ins><span class="cx"> else: </span><span class="cx"> self.primarytable = self.table </span><ins>+ self.noninherited_table = self.table </ins><span class="cx"> self._synchronizer = None </span><span class="cx"> self.inherits = None </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemymappingpropertiespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py (1116 => 1117)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-08 22:32:55 UTC (rev 1116) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-09 00:24:15 UTC (rev 1117) </span><span class="lines">@@ -172,17 +172,12 @@ </span><span class="cx"> # if join conditions were not specified, figure them out based on foreign keys </span><span class="cx"> if self.secondary is not None: </span><span class="cx"> if self.secondaryjoin is None: </span><del>- self.secondaryjoin = sql.join(self.target, self.secondary).onclause </del><ins>+ self.secondaryjoin = sql.join(self.mapper.noninherited_table, self.secondary).onclause </ins><span class="cx"> if self.primaryjoin is None: </span><del>- self.primaryjoin = sql.join(parent.table, self.secondary).onclause - tf = mapper.TableFinder(self.secondaryjoin, check_columns=True) - tf2 = mapper.TableFinder(self.primaryjoin, check_columns=True) - for t in tf2: - if t is not self.secondary and t in tf: - raise ArgumentError("Ambiguous join conditions generated between '%s' and '%s' (primaryjoin='%s', secondaryjoin='%s'); please specify explicit primaryjoin and/or secondaryjoin arguments to property '%s'" % (parent.table.id, self.target.id, self.primaryjoin, self.secondaryjoin, self.key)) </del><ins>+ self.primaryjoin = sql.join(parent.noninherited_table, self.secondary).onclause </ins><span class="cx"> else: </span><span class="cx"> if self.primaryjoin is None: </span><del>- self.primaryjoin = sql.join(parent.table, self.target).onclause </del><ins>+ self.primaryjoin = sql.join(parent.noninherited_table, self.target).onclause </ins><span class="cx"> # if the foreign key wasnt specified and theres no assocaition table, try to figure </span><span class="cx"> # out who is dependent on who. we dont need all the foreign keys represented in the join, </span><span class="cx"> # just one of them. </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/sql.py (1116 => 1117)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-08 22:32:55 UTC (rev 1116) +++ sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-09 00:24:15 UTC (rev 1117) </span><span class="lines">@@ -1132,6 +1132,7 @@ </span><span class="cx"> self.selects = selects </span><span class="cx"> self.use_labels = kwargs.pop('use_labels', False) </span><span class="cx"> self.parens = kwargs.pop('parens', False) </span><ins>+ self.correlate = kwargs.pop('correlate', False) </ins><span class="cx"> self.oid_column = selects[0].oid_column </span><span class="cx"> for s in self.selects: </span><span class="cx"> s.group_by(None) </span></span></pre></div> <a id="sqlalchemytrunktestinheritancepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/inheritance.py (1116 => 1117)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/inheritance.py 2006-03-08 22:32:55 UTC (rev 1116) +++ sqlalchemy/trunk/test/inheritance.py 2006-03-09 00:24:15 UTC (rev 1117) </span><span class="lines">@@ -132,8 +132,8 @@ </span><span class="cx"> #'id':[bar.c.bid, foo.c.id] </span><span class="cx"> }) </span><span class="cx"> </span><del>- Bar.mapper.add_property('foos', relation(Foo.mapper, foo_bar, primaryjoin=bar.c.bid==foo_bar.c.bar_id, secondaryjoin=foo_bar.c.foo_id==foo.c.id, lazy=False)) - #Bar.mapper.add_property('foos', relation(Foo.mapper, foo_bar, lazy=False)) </del><ins>+ #Bar.mapper.add_property('foos', relation(Foo.mapper, foo_bar, primaryjoin=bar.c.bid==foo_bar.c.bar_id, secondaryjoin=foo_bar.c.foo_id==foo.c.id, lazy=False)) + Bar.mapper.add_property('foos', relation(Foo.mapper, foo_bar, lazy=False)) </ins><span class="cx"> </span><span class="cx"> b = Bar('barfoo') </span><span class="cx"> objectstore.commit() </span><span class="lines">@@ -209,8 +209,8 @@ </span><span class="cx"> return "Bar id %d, data %s" % (self.id, self.data) </span><span class="cx"> </span><span class="cx"> Bar.mapper = mapper(Bar, bar, inherits=Foo.mapper, properties={ </span><del>- 'foos' :relation(Foo.mapper, bar_foo, primaryjoin=bar.c.id==bar_foo.c.bar_id, lazy=False) -# 'foos' :relation(Foo.mapper, bar_foo, lazy=True) </del><ins>+ #'foos' :relation(Foo.mapper, bar_foo, primaryjoin=bar.c.id==bar_foo.c.bar_id, lazy=False) + 'foos' :relation(Foo.mapper, bar_foo, lazy=True) </ins><span class="cx"> }) </span><span class="cx"> </span><span class="cx"> b = Bar('bar #1') </span><span class="lines">@@ -239,8 +239,10 @@ </span><span class="cx"> return "Blub id %d, data %s, bars %s, foos %s" % (self.id, self.data, repr([b for b in self.bars]), repr([f for f in self.foos])) </span><span class="cx"> </span><span class="cx"> Blub.mapper = mapper(Blub, blub, inherits=Bar.mapper, properties={ </span><del>- 'bars':relation(Bar.mapper, blub_bar, primaryjoin=blub.c.id==blub_bar.c.blub_id, lazy=False), - 'foos':relation(Foo.mapper, blub_foo, primaryjoin=blub.c.id==blub_foo.c.blub_id, lazy=False), </del><ins>+# 'bars':relation(Bar.mapper, blub_bar, primaryjoin=blub.c.id==blub_bar.c.blub_id, lazy=False), +# 'foos':relation(Foo.mapper, blub_foo, primaryjoin=blub.c.id==blub_foo.c.blub_id, lazy=False), + 'bars':relation(Bar.mapper, blub_bar, lazy=False), + 'foos':relation(Foo.mapper, blub_foo, lazy=False), </ins><span class="cx"> }) </span><span class="cx"> </span><span class="cx"> useobjects = True </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-08 22:33:08
|
<!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>[1116] sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py: a few tweaks to get table creates/reflection working</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1116</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-08 16:32:55 -0600 (Wed, 08 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>a few tweaks to get table creates/reflection working table names are always reflected back as having lowercase names</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemydatabasesoraclepy">sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemydatabasesoraclepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py (1115 => 1116)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py 2006-03-08 22:11:51 UTC (rev 1115) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py 2006-03-08 22:32:55 UTC (rev 1116) </span><span class="lines">@@ -123,13 +123,14 @@ </span><span class="cx"> return OracleDefaultRunner(self, proxy) </span><span class="cx"> </span><span class="cx"> def reflecttable(self, table): </span><del>- c = self.execute ("select COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE, DATA_DEFAULT from USER_TAB_COLUMNS where TABLE_NAME = :table_name", {'table_name':table.name}) </del><ins>+ c = self.execute ("select COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE, DATA_DEFAULT from USER_TAB_COLUMNS where TABLE_NAME = :table_name", {'table_name':table.name.upper()}) </ins><span class="cx"> </span><span class="cx"> while True: </span><span class="cx"> row = c.fetchone() </span><span class="cx"> if row is None: </span><span class="cx"> break </span><span class="cx"> </span><ins>+ #print "ROW:" , row </ins><span class="cx"> (name, coltype, length, precision, scale, nullable, default) = (row[0], row[1], row[2], row[3], row[4], row[5]=='Y', row[6]) </span><span class="cx"> </span><span class="cx"> # INTEGER if the scale is 0 and precision is null </span><span class="lines">@@ -163,17 +164,17 @@ </span><span class="cx"> where UCC.CONSTRAINT_NAME = UC.CONSTRAINT_NAME </span><span class="cx"> and UC.R_CONSTRAINT_NAME = UC2.CONSTRAINT_NAME(+) </span><span class="cx"> and UCC.TABLE_NAME = :table_name </span><del>-order by UCC.CONSTRAINT_NAME""",{'table_name' : table.name}) </del><ins>+order by UCC.CONSTRAINT_NAME""",{'table_name' : table.name.upper()}) </ins><span class="cx"> while True: </span><span class="cx"> row = c.fetchone() </span><span class="cx"> if row is None: </span><span class="cx"> break </span><del>- </del><ins>+ #print "ROW:" , row </ins><span class="cx"> (cons_name, column_name, type, search, referred_table) = row </span><span class="cx"> if type=='P' : </span><span class="cx"> table.c[column_name.lower()]._set_primary_key() </span><span class="cx"> elif type=='R': </span><del>- remotetable = Table(referred_table, table.engine, autoload = True) </del><ins>+ remotetable = Table(referred_table.lower(), table.engine, autoload = True) </ins><span class="cx"> table.c[column_name.lower()].append_item(schema.ForeignKey(remotetable.primary_key[0])) </span><span class="cx"> </span><span class="cx"> def last_inserted_ids(self): </span><span class="lines">@@ -310,7 +311,7 @@ </span><span class="cx"> if column.primary_key and not override_pk: </span><span class="cx"> colspec += " PRIMARY KEY" </span><span class="cx"> if column.foreign_key: </span><del>- colspec += " REFERENCES %s(%s)" % (column.column.foreign_key.column.table.name, column.column.foreign_key.column.name) </del><ins>+ colspec += " REFERENCES %s(%s)" % (column.foreign_key.column.table.name, column.foreign_key.column.name) </ins><span class="cx"> return colspec </span><span class="cx"> </span><span class="cx"> def visit_sequence(self, sequence): </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-08 22:12:02
|
<!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>[1115] sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py: tweak to engine param..</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1115</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-08 16:11:51 -0600 (Wed, 08 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>tweak to engine param..</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemydatabasesoraclepy">sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemydatabasesoraclepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py (1114 => 1115)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py 2006-03-08 21:55:33 UTC (rev 1114) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py 2006-03-08 22:11:51 UTC (rev 1115) </span><span class="lines">@@ -173,7 +173,7 @@ </span><span class="cx"> if type=='P' : </span><span class="cx"> table.c[column_name.lower()]._set_primary_key() </span><span class="cx"> elif type=='R': </span><del>- remotetable = Table(referred_table, referred_table.engine, autoload = True) </del><ins>+ remotetable = Table(referred_table, table.engine, autoload = True) </ins><span class="cx"> table.c[column_name.lower()].append_item(schema.ForeignKey(remotetable.primary_key[0])) </span><span class="cx"> </span><span class="cx"> def last_inserted_ids(self): </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-08 21:55:42
|
<!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>[1114] sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py: added identity() method to mapper, to help get the primary key of an instance.</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1114</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-08 15:55:33 -0600 (Wed, 08 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>added identity() method to mapper, to help get the primary key of an instance.</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemymappingmapperpy">sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemymappingmapperpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py (1113 => 1114)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-08 21:39:53 UTC (rev 1113) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-08 21:55:33 UTC (rev 1114) </span><span class="lines">@@ -306,11 +306,17 @@ </span><span class="cx"> </span><span class="cx"> </span><span class="cx"> def identity_key(self, *primary_key): </span><ins>+ """returns the instance key for the given identity value. this is a global tracking object used by the objectstore, and is usually available off a mapped object as instance._instance_key.""" </ins><span class="cx"> return objectstore.get_id_key(tuple(primary_key), self.class_) </span><span class="cx"> </span><span class="cx"> def instance_key(self, instance): </span><del>- return self.identity_key(*[self._getattrbycolumn(instance, column) for column in self.pks_by_table[self.table]]) </del><ins>+ """returns the instance key for the given instance. this is a global tracking object used by the objectstore, and is usually available off a mapped object as instance._instance_key.""" + return self.identity_key(*self.identity(instance)) </ins><span class="cx"> </span><ins>+ def identity(self, instance): + """returns the identity (list of primary key values) for the given instance. The list of values can be fed directly into the get() method as mapper.get(*key).""" + return [self._getattrbycolumn(instance, column) for column in self.pks_by_table[self.table]] + </ins><span class="cx"> def compile(self, whereclause = None, **options): </span><span class="cx"> """works like select, except returns the SQL statement object without </span><span class="cx"> compiling or executing it""" </span></span></pre> </div> </div> </body> </html> |
<!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>[1113] sqlalchemy/trunk/test: added check to relation that will see if the same table is included between the primaryjoin and secondaryjoin, and raises a descriptive exception if so.</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1113</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-08 15:39:53 -0600 (Wed, 08 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>added check to relation that will see if the same table is included between the primaryjoin and secondaryjoin, and raises a descriptive exception if so.</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemymappingmapperpy">sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemymappingpropertiespy">sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py</a></li> <li><a href="#sqlalchemytrunktestinheritancepy">sqlalchemy/trunk/test/inheritance.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemymappingmapperpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py (1112 => 1113)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-08 20:51:51 UTC (rev 1112) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-08 21:39:53 UTC (rev 1113) </span><span class="lines">@@ -936,8 +936,9 @@ </span><span class="cx"> </span><span class="cx"> class TableFinder(sql.ClauseVisitor): </span><span class="cx"> """given a Clause, locates all the Tables within it into a list.""" </span><del>- def __init__(self, table): </del><ins>+ def __init__(self, table, check_columns=False): </ins><span class="cx"> self.tables = [] </span><ins>+ self.check_columns = check_columns </ins><span class="cx"> table.accept_visitor(self) </span><span class="cx"> def visit_table(self, table): </span><span class="cx"> self.tables.append(table) </span><span class="lines">@@ -951,7 +952,10 @@ </span><span class="cx"> return obj in self.tables </span><span class="cx"> def __add__(self, obj): </span><span class="cx"> return self.tables + obj </span><del>- </del><ins>+ def visit_column(self, column): + if self.check_columns: + column.table.accept_visitor(self) + </ins><span class="cx"> def hash_key(obj): </span><span class="cx"> if obj is None: </span><span class="cx"> return 'None' </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemymappingpropertiespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py (1112 => 1113)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-08 20:51:51 UTC (rev 1112) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-08 21:39:53 UTC (rev 1113) </span><span class="lines">@@ -175,6 +175,11 @@ </span><span class="cx"> self.secondaryjoin = sql.join(self.target, self.secondary).onclause </span><span class="cx"> if self.primaryjoin is None: </span><span class="cx"> self.primaryjoin = sql.join(parent.table, self.secondary).onclause </span><ins>+ tf = mapper.TableFinder(self.secondaryjoin, check_columns=True) + tf2 = mapper.TableFinder(self.primaryjoin, check_columns=True) + for t in tf2: + if t is not self.secondary and t in tf: + raise ArgumentError("Ambiguous join conditions generated between '%s' and '%s' (primaryjoin='%s', secondaryjoin='%s'); please specify explicit primaryjoin and/or secondaryjoin arguments to property '%s'" % (parent.table.id, self.target.id, self.primaryjoin, self.secondaryjoin, self.key)) </ins><span class="cx"> else: </span><span class="cx"> if self.primaryjoin is None: </span><span class="cx"> self.primaryjoin = sql.join(parent.table, self.target).onclause </span></span></pre></div> <a id="sqlalchemytrunktestinheritancepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/inheritance.py (1112 => 1113)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/inheritance.py 2006-03-08 20:51:51 UTC (rev 1112) +++ sqlalchemy/trunk/test/inheritance.py 2006-03-08 21:39:53 UTC (rev 1113) </span><span class="lines">@@ -192,21 +192,34 @@ </span><span class="cx"> table.drop() </span><span class="cx"> testbase.db.tables.clear() </span><span class="cx"> </span><ins>+ def tearDown(self): + for table in reversed(tables): + table.delete().execute() + </ins><span class="cx"> def testbasic(self): </span><span class="cx"> class Foo(object): </span><ins>+ def __init__(self, data=None): + self.data = data </ins><span class="cx"> def __repr__(self): </span><span class="cx"> return "Foo id %d, data %s" % (self.id, self.data) </span><span class="cx"> Foo.mapper = mapper(Foo, foo) </span><span class="cx"> </span><del>- class Bar(object): </del><ins>+ class Bar(Foo): </ins><span class="cx"> def __repr__(self): </span><span class="cx"> return "Bar id %d, data %s" % (self.id, self.data) </span><span class="cx"> </span><span class="cx"> Bar.mapper = mapper(Bar, bar, inherits=Foo.mapper, properties={ </span><del>- 'foos' :relation(Foo.mapper, bar_foo, primaryjoin=bar.c.id==bar_foo.c.bar_id, secondaryjoin=bar_foo.c.foo_id==foo.c.id, lazy=False) </del><ins>+ 'foos' :relation(Foo.mapper, bar_foo, primaryjoin=bar.c.id==bar_foo.c.bar_id, lazy=False) +# 'foos' :relation(Foo.mapper, bar_foo, lazy=True) </ins><span class="cx"> }) </span><span class="cx"> </span><del>- Bar.mapper.select() </del><ins>+ b = Bar('bar #1') + b.foos.append(Foo("foo #1")) + b.foos.append(Foo("foo #2")) + objectstore.commit() + objectstore.clear() + l = Bar.mapper.select() + print l[0], l[0].foos </ins><span class="cx"> </span><span class="cx"> def testadvanced(self): </span><span class="cx"> class Foo(object): </span><span class="lines">@@ -226,8 +239,8 @@ </span><span class="cx"> return "Blub id %d, data %s, bars %s, foos %s" % (self.id, self.data, repr([b for b in self.bars]), repr([f for f in self.foos])) </span><span class="cx"> </span><span class="cx"> Blub.mapper = mapper(Blub, blub, inherits=Bar.mapper, properties={ </span><del>- 'bars':relation(Bar.mapper, blub_bar, primaryjoin=blub.c.id==blub_bar.c.blub_id, secondaryjoin=blub_bar.c.bar_id==bar.c.id, lazy=False), - 'foos':relation(Foo.mapper, blub_foo, primaryjoin=blub.c.id==blub_foo.c.blub_id, secondaryjoin=blub_foo.c.foo_id==foo.c.id, lazy=False), </del><ins>+ 'bars':relation(Bar.mapper, blub_bar, primaryjoin=blub.c.id==blub_bar.c.blub_id, lazy=False), + 'foos':relation(Foo.mapper, blub_foo, primaryjoin=blub.c.id==blub_foo.c.blub_id, lazy=False), </ins><span class="cx"> }) </span><span class="cx"> </span><span class="cx"> useobjects = True </span><span class="lines">@@ -252,13 +265,13 @@ </span><span class="cx"> blub_foo.insert().execute(blub_id=1, foo_id=2) </span><span class="cx"> </span><span class="cx"> l = Blub.mapper.select() </span><del>- for x in l: - print x - </del><ins>+ self.echo(l) </ins><span class="cx"> self.assert_(repr(l[0]) == compare) </span><span class="cx"> objectstore.clear() </span><span class="cx"> x = Blub.mapper.get_by(id=blubid) #traceback 2 </span><ins>+ self.echo(x) </ins><span class="cx"> self.assert_(repr(x) == compare) </span><ins>+ </ins><span class="cx"> </span><span class="cx"> </span><span class="cx"> if __name__ == "__main__": </span></span></pre> </div> </div> </body> </html> |
<!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>[1112] sqlalchemy/trunk/test: serious overhaul to get eager loads to work inline with an inheriting mapper, when the inheritance/eager loads share the same table.</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1112</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-08 14:51:51 -0600 (Wed, 08 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>serious overhaul to get eager loads to work inline with an inheriting mapper, when the inheritance/eager loads share the same table. mapper inheritance will also favor the columns from the child table over those of the parent table when assigning column values to object attributes. "correlated subqueries" require a flag "correlated=True" if they are in the FROM clause of another SELECT statement, and they want to be correlated. this flag is set by default when using an "exists" clause.</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemyenginepy">sqlalchemy/trunk/lib/sqlalchemy/engine.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemymappingmapperpy">sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemymappingpropertiespy">sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemysqlpy">sqlalchemy/trunk/lib/sqlalchemy/sql.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemyutilpy">sqlalchemy/trunk/lib/sqlalchemy/util.py</a></li> <li><a href="#sqlalchemytrunktestinheritancepy">sqlalchemy/trunk/test/inheritance.py</a></li> <li><a href="#sqlalchemytrunktestselectpy">sqlalchemy/trunk/test/select.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemyenginepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/engine.py (1111 => 1112)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/engine.py 2006-03-08 01:18:26 UTC (rev 1111) +++ sqlalchemy/trunk/lib/sqlalchemy/engine.py 2006-03-08 20:51:51 UTC (rev 1112) </span><span class="lines">@@ -712,6 +712,7 @@ </span><span class="cx"> if self.props.setdefault(colname, rec) is not rec: </span><span class="cx"> self.props[colname] = (ResultProxy.AmbiguousColumn(colname), 0) </span><span class="cx"> self.keys.append(colname) </span><ins>+ #print "COLNAME", colname </ins><span class="cx"> self.props[i] = rec </span><span class="cx"> i+=1 </span><span class="cx"> </span><span class="lines">@@ -719,6 +720,7 @@ </span><span class="cx"> if isinstance(key, schema.Column) or isinstance(key, sql.ColumnElement): </span><span class="cx"> try: </span><span class="cx"> rec = self.props[key._label.lower()] </span><ins>+ #print "GOT IT FROM LABEL FOR ", key._label </ins><span class="cx"> except KeyError: </span><span class="cx"> try: </span><span class="cx"> rec = self.props[key.key.lower()] </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemymappingmapperpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py (1111 => 1112)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-08 01:18:26 UTC (rev 1111) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/mapper.py 2006-03-08 20:51:51 UTC (rev 1112) </span><span class="lines">@@ -145,7 +145,12 @@ </span><span class="cx"> prop = ColumnProperty(column) </span><span class="cx"> self.props[column.key] = prop </span><span class="cx"> elif isinstance(prop, ColumnProperty): </span><del>- prop.columns.append(column) </del><ins>+ # the order which columns are appended to a ColumnProperty is significant, as the + # column at index 0 determines which result column is used to populate the object + # attribute, in the case of mapping against a join with column names repeated + # (and particularly in an inheritance relationship) + prop.columns.insert(0, column) + #prop.columns.append(column) </ins><span class="cx"> else: </span><span class="cx"> if not allow_column_override: </span><span class="cx"> raise ArgumentError("WARNING: column '%s' not being added due to property '%s'. Specify 'allow_column_override=True' to mapper() to ignore this condition." % (column.key, repr(prop))) </span><span class="lines">@@ -179,6 +184,12 @@ </span><span class="cx"> if getattr(prop, 'key', None) is None: </span><span class="cx"> prop.init(key, self) </span><span class="cx"> </span><ins>+ # this prints a summary of the object attributes and how they + # will be mapped to table columns + #print "mapper %s, columntoproperty:" % (self.class_.__name__) + #for key, value in self.columntoproperty.iteritems(): + # print key.table.name, key.key, [(v.key, v) for v in value] + </ins><span class="cx"> engines = property(lambda s: [t.engine for t in s.tables]) </span><span class="cx"> </span><span class="cx"> def add_property(self, key, prop): </span><span class="lines">@@ -638,9 +649,7 @@ </span><span class="cx"> def delete_obj(self, objects, uow): </span><span class="cx"> """called by a UnitOfWork object to delete objects, which involves a </span><span class="cx"> DELETE statement for each table used by this mapper, for each object in the list.""" </span><del>- l = list(self.tables) - l.reverse() - for table in l: </del><ins>+ for table in util.reversed(self.tables): </ins><span class="cx"> if not self._has_pks(table): </span><span class="cx"> continue </span><span class="cx"> delete = [] </span><span class="lines">@@ -703,7 +712,8 @@ </span><span class="cx"> order_by = self.table.default_order_by() </span><span class="cx"> </span><span class="cx"> if self._should_nest(**kwargs): </span><del>- s2 = sql.select(self.table.primary_key, whereclause, use_labels=True, **kwargs) </del><ins>+ s2 = sql.select(self.table.primary_key, whereclause, use_labels=True, from_obj=[self.table], **kwargs) +# raise "ok first thing", str(s2) </ins><span class="cx"> if not kwargs.get('distinct', False) and order_by: </span><span class="cx"> s2.order_by(*util.to_list(order_by)) </span><span class="cx"> s3 = s2.alias('rowcount') </span><span class="lines">@@ -711,6 +721,7 @@ </span><span class="cx"> for i in range(0, len(self.table.primary_key)): </span><span class="cx"> crit.append(s3.primary_key[i] == self.table.primary_key[i]) </span><span class="cx"> statement = sql.select([], sql.and_(*crit), from_obj=[self.table], use_labels=True) </span><ins>+ # raise "OK statement", str(statement) </ins><span class="cx"> if order_by: </span><span class="cx"> statement.order_by(*util.to_list(order_by)) </span><span class="cx"> else: </span><span class="lines">@@ -930,6 +941,8 @@ </span><span class="cx"> table.accept_visitor(self) </span><span class="cx"> def visit_table(self, table): </span><span class="cx"> self.tables.append(table) </span><ins>+ def __len__(self): + return len(self.tables) </ins><span class="cx"> def __getitem__(self, i): </span><span class="cx"> return self.tables[i] </span><span class="cx"> def __iter__(self): </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemymappingpropertiespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py (1111 => 1112)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-08 01:18:26 UTC (rev 1111) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-08 20:51:51 UTC (rev 1112) </span><span class="lines">@@ -48,6 +48,7 @@ </span><span class="cx"> objectstore.uow().register_attribute(parent.class_, key, uselist = False) </span><span class="cx"> def execute(self, instance, row, identitykey, imap, isnew): </span><span class="cx"> if isnew: </span><ins>+ #print "POPULATING OBJ", instance.__class__.__name__, "COL", self.columns[0]._label, "WITH DATA", row[self.columns[0]], "ROW IS A", row.__class__.__name__, "COL ID", id(self.columns[0]) </ins><span class="cx"> instance.__dict__[self.key] = row[self.columns[0]] </span><span class="cx"> def __repr__(self): </span><span class="cx"> return "ColumnProperty(%s)" % repr([str(c) for c in self.columns]) </span><span class="lines">@@ -648,16 +649,19 @@ </span><span class="cx"> parent._has_eager = True </span><span class="cx"> </span><span class="cx"> self.eagertarget = self.target.alias() </span><ins>+# print "ALIAS", str(self.eagertarget.select()) #selectable.__class__.__name__ </ins><span class="cx"> if self.secondary: </span><span class="cx"> self.eagersecondary = self.secondary.alias() </span><span class="cx"> self.aliasizer = Aliasizer(self.target, self.secondary, aliases={ </span><span class="cx"> self.target:self.eagertarget, </span><span class="cx"> self.secondary:self.eagersecondary </span><span class="cx"> }) </span><ins>+ #print "TARGET", self.target </ins><span class="cx"> self.eagersecondaryjoin = self.secondaryjoin.copy_container() </span><span class="cx"> self.eagersecondaryjoin.accept_visitor(self.aliasizer) </span><span class="cx"> self.eagerprimary = self.primaryjoin.copy_container() </span><span class="cx"> self.eagerprimary.accept_visitor(self.aliasizer) </span><ins>+ #print "JOINS:", str(self.eagerprimary), "|", str(self.eagersecondaryjoin) </ins><span class="cx"> else: </span><span class="cx"> self.aliasizer = Aliasizer(self.target, aliases={self.target:self.eagertarget}) </span><span class="cx"> self.eagerprimary = self.primaryjoin.copy_container() </span><span class="lines">@@ -778,7 +782,8 @@ </span><span class="cx"> """gets an instance from a row, via this EagerLoader's mapper.""" </span><span class="cx"> fakerow = util.DictDecorator(row) </span><span class="cx"> for c in self.eagertarget.c: </span><del>- fakerow[c.parent] = row[c] </del><ins>+ parent = self.target._get_col_by_original(c.original) + fakerow[parent] = row[c] </ins><span class="cx"> row = fakerow </span><span class="cx"> return self.mapper._instance(row, imap, result_list) </span><span class="cx"> </span><span class="lines">@@ -882,15 +887,18 @@ </span><span class="cx"> """converts a table instance within an expression to be an alias of that table.""" </span><span class="cx"> def __init__(self, *tables, **kwargs): </span><span class="cx"> self.tables = {} </span><ins>+ self.aliases = kwargs.get('aliases', {}) </ins><span class="cx"> for t in tables: </span><span class="cx"> self.tables[t] = t </span><ins>+ if not self.aliases.has_key(t): + self.aliases[t] = sql.alias(t) + if isinstance(t, sql.Join): + for t2 in t.columns: + self.tables[t2.table] = t2 + self.aliases[t2.table] = self.aliases[t] </ins><span class="cx"> self.binary = None </span><del>- self.aliases = kwargs.get('aliases', {}) </del><span class="cx"> def get_alias(self, table): </span><del>- try: - return self.aliases[table] - except: - return self.aliases.setdefault(table, sql.alias(table)) </del><ins>+ return self.aliases[table] </ins><span class="cx"> def visit_compound(self, compound): </span><span class="cx"> self.visit_clauselist(compound) </span><span class="cx"> def visit_clauselist(self, clist): </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/sql.py (1111 => 1112)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-08 01:18:26 UTC (rev 1111) +++ sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-08 20:51:51 UTC (rev 1112) </span><span class="lines">@@ -129,6 +129,7 @@ </span><span class="cx"> return BooleanExpression(ctest, and_(cleft, cright), 'BETWEEN') </span><span class="cx"> </span><span class="cx"> def exists(*args, **params): </span><ins>+ params['correlate'] = True </ins><span class="cx"> s = select(*args, **params) </span><span class="cx"> return BooleanExpression(TextClause("EXISTS"), s, None) </span><span class="cx"> </span><span class="lines">@@ -839,7 +840,7 @@ </span><span class="cx"> self.left = left </span><span class="cx"> self.right = right </span><span class="cx"> self.id = self.left.id + "_" + self.right.id </span><del>- </del><ins>+ </ins><span class="cx"> # TODO: if no onclause, do NATURAL JOIN </span><span class="cx"> if onclause is None: </span><span class="cx"> self.onclause = self._match_primaries(left, right) </span><span class="lines">@@ -852,7 +853,7 @@ </span><span class="cx"> def _exportable_columns(self): </span><span class="cx"> return [c for c in self.left.columns] + [c for c in self.right.columns] </span><span class="cx"> def _proxy_column(self, column): </span><del>- self._columns[column.table.name + "_" + column.key] = column </del><ins>+ self._columns[column._label] = column </ins><span class="cx"> if column.primary_key: </span><span class="cx"> self._primary_key.append(column) </span><span class="cx"> if column.foreign_key: </span><span class="lines">@@ -894,7 +895,9 @@ </span><span class="cx"> self.join = join </span><span class="cx"> def _exportable_columns(self): </span><span class="cx"> return [] </span><del>- </del><ins>+ + def alias(self, name=None): + return self.select(use_labels=True).alias(name) </ins><span class="cx"> def _process_from_dict(self, data, asfrom): </span><span class="cx"> for f in self.onclause._get_from_objects(): </span><span class="cx"> data[f.id] = f </span><span class="lines">@@ -915,7 +918,7 @@ </span><span class="cx"> self.original = baseselectable </span><span class="cx"> self.selectable = selectable </span><span class="cx"> if alias is None: </span><del>- n = getattr(self.original, 'name') </del><ins>+ n = getattr(self.original, 'name', None) </ins><span class="cx"> if n is None: </span><span class="cx"> n = 'anon' </span><span class="cx"> elif len(n) > 15: </span><span class="lines">@@ -974,7 +977,7 @@ </span><span class="cx"> self.__label = None </span><span class="cx"> def _get_label(self): </span><span class="cx"> if self.__label is None: </span><del>- if self.table is not None: </del><ins>+ if self.table is not None and self.table.name is not None: </ins><span class="cx"> self.__label = self.table.name + "_" + self.text </span><span class="cx"> else: </span><span class="cx"> self.__label = self.text </span><span class="lines">@@ -1164,7 +1167,7 @@ </span><span class="cx"> class Select(SelectBaseMixin, FromClause): </span><span class="cx"> """represents a SELECT statement, with appendable clauses, as well as </span><span class="cx"> the ability to execute itself and return a result set.""" </span><del>- def __init__(self, columns=None, whereclause = None, from_obj = [], order_by = None, group_by=None, having=None, use_labels = False, distinct=False, engine = None, limit=None, offset=None): </del><ins>+ def __init__(self, columns=None, whereclause = None, from_obj = [], order_by = None, group_by=None, having=None, use_labels = False, distinct=False, engine = None, limit=None, offset=None, correlate=False): </ins><span class="cx"> self._froms = util.OrderedDict() </span><span class="cx"> self.use_labels = use_labels </span><span class="cx"> self.id = "Select(%d)" % id(self) </span><span class="lines">@@ -1175,6 +1178,7 @@ </span><span class="cx"> self.oid_column = None </span><span class="cx"> self.limit = limit </span><span class="cx"> self.offset = offset </span><ins>+ self.correlate = correlate </ins><span class="cx"> </span><span class="cx"> # indicates if this select statement is a subquery inside another query </span><span class="cx"> self.issubquery = False </span><span class="lines">@@ -1224,9 +1228,11 @@ </span><span class="cx"> select.is_where = self.is_where </span><span class="cx"> select.issubquery = True </span><span class="cx"> select.parens = True </span><ins>+ if not self.is_where and not select.correlate: + return </ins><span class="cx"> if getattr(select, '_correlated', None) is None: </span><span class="cx"> select._correlated = self.select._froms </span><del>- </del><ins>+ </ins><span class="cx"> def append_column(self, column): </span><span class="cx"> if _is_literal(column): </span><span class="cx"> column = ColumnClause(str(column), self) </span><span class="lines">@@ -1266,7 +1272,8 @@ </span><span class="cx"> def append_from(self, fromclause): </span><span class="cx"> if type(fromclause) == str: </span><span class="cx"> fromclause = FromClause(from_name = fromclause) </span><del>- </del><ins>+ if self.oid_column is None and hasattr(fromclause, 'oid_column'): + self.oid_column = fromclause.oid_column </ins><span class="cx"> fromclause.accept_visitor(self._correlator) </span><span class="cx"> fromclause._process_from_dict(self._froms, True) </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemyutilpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/util.py (1111 => 1112)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/util.py 2006-03-08 01:18:26 UTC (rev 1111) +++ sqlalchemy/trunk/lib/sqlalchemy/util.py 2006-03-08 20:51:51 UTC (rev 1112) </span><span class="lines">@@ -7,6 +7,7 @@ </span><span class="cx"> __all__ = ['OrderedProperties', 'OrderedDict', 'generic_repr', 'HashSet', 'AttrProp'] </span><span class="cx"> import thread, threading, weakref, UserList, time, string, inspect, sys </span><span class="cx"> from exceptions import * </span><ins>+import __builtin__ </ins><span class="cx"> </span><span class="cx"> def to_list(x): </span><span class="cx"> if x is None: </span><span class="lines">@@ -24,6 +25,18 @@ </span><span class="cx"> else: </span><span class="cx"> return x </span><span class="cx"> </span><ins>+def reversed(seq): + try: + return __builtin__.reversed(seq) + except: + def rev(): + i = len(seq) -1 + while i >= 0: + yield seq[i] + i -= 1 + raise StopIteration() + return rev() + </ins><span class="cx"> class AttrProp(object): </span><span class="cx"> """a quick way to stick a property accessor on an object""" </span><span class="cx"> def __init__(self, key): </span></span></pre></div> <a id="sqlalchemytrunktestinheritancepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/inheritance.py (1111 => 1112)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/inheritance.py 2006-03-08 01:18:26 UTC (rev 1111) +++ sqlalchemy/trunk/test/inheritance.py 2006-03-08 20:51:51 UTC (rev 1112) </span><span class="lines">@@ -2,9 +2,8 @@ </span><span class="cx"> import testbase </span><span class="cx"> import string </span><span class="cx"> import sqlalchemy.attributes as attr </span><ins>+import sys </ins><span class="cx"> </span><del>- - </del><span class="cx"> class Principal( object ): </span><span class="cx"> pass </span><span class="cx"> </span><span class="lines">@@ -54,8 +53,6 @@ </span><span class="cx"> </span><span class="cx"> ) </span><span class="cx"> </span><del>- - </del><span class="cx"> principals.create() </span><span class="cx"> users.create() </span><span class="cx"> groups.create() </span><span class="lines">@@ -65,6 +62,7 @@ </span><span class="cx"> groups.drop() </span><span class="cx"> users.drop() </span><span class="cx"> principals.drop() </span><ins>+ testbase.db.tables.clear() </ins><span class="cx"> def setUp(self): </span><span class="cx"> objectstore.clear() </span><span class="cx"> clear_mappers() </span><span class="lines">@@ -111,6 +109,7 @@ </span><span class="cx"> foo_bar.drop() </span><span class="cx"> bar.drop() </span><span class="cx"> foo.drop() </span><ins>+ testbase.db.tables.clear() </ins><span class="cx"> </span><span class="cx"> def testbasic(self): </span><span class="cx"> class Foo(object): </span><span class="lines">@@ -155,6 +154,112 @@ </span><span class="cx"> {'id':b.id, 'data':'barfoo', 'foos':(Foo, [{'id':f1.id,'data':'subfoo1'}, {'id':f2.id,'data':'subfoo2'}])}, </span><span class="cx"> ) </span><span class="cx"> </span><ins>+class InheritTest3(testbase.AssertMixin): + def setUpAll(self): + engine = testbase.db + global foo, bar, blub, bar_foo, blub_bar, blub_foo,tables + engine.engine.echo = 'debug' + # the 'data' columns are to appease SQLite which cant handle a blank INSERT + foo = Table('foo', engine, + Column('id', Integer, Sequence('foo_seq'), primary_key=True), + Column('data', String(20))) </ins><span class="cx"> </span><ins>+ bar = Table('bar', engine, + Column('id', Integer, ForeignKey('foo.id'), primary_key=True), + Column('data', String(20))) + + blub = Table('blub', engine, + Column('id', Integer, ForeignKey('bar.id'), primary_key=True), + Column('data', String(20))) + + bar_foo = Table('bar_foo', engine, + Column('bar_id', Integer, ForeignKey('bar.id')), + Column('foo_id', Integer, ForeignKey('foo.id'))) + + blub_bar = Table('bar_blub', engine, + Column('blub_id', Integer, ForeignKey('blub.id')), + Column('bar_id', Integer, ForeignKey('bar.id'))) + + blub_foo = Table('blub_foo', engine, + Column('blub_id', Integer, ForeignKey('blub.id')), + Column('foo_id', Integer, ForeignKey('foo.id'))) + + tables = [foo, bar, blub, bar_foo, blub_bar, blub_foo] + for table in tables: + table.create() + def tearDownAll(self): + for table in reversed(tables): + table.drop() + testbase.db.tables.clear() + + def testbasic(self): + class Foo(object): + def __repr__(self): + return "Foo id %d, data %s" % (self.id, self.data) + Foo.mapper = mapper(Foo, foo) + + class Bar(object): + def __repr__(self): + return "Bar id %d, data %s" % (self.id, self.data) + + Bar.mapper = mapper(Bar, bar, inherits=Foo.mapper, properties={ + 'foos' :relation(Foo.mapper, bar_foo, primaryjoin=bar.c.id==bar_foo.c.bar_id, secondaryjoin=bar_foo.c.foo_id==foo.c.id, lazy=False) + }) + + Bar.mapper.select() + + def testadvanced(self): + class Foo(object): + def __init__(self, data=None): + self.data = data + def __repr__(self): + return "Foo id %d, data %s" % (self.id, self.data) + Foo.mapper = mapper(Foo, foo) + + class Bar(Foo): + def __repr__(self): + return "Bar id %d, data %s" % (self.id, self.data) + Bar.mapper = mapper(Bar, bar, inherits=Foo.mapper) + + class Blub(Bar): + def __repr__(self): + return "Blub id %d, data %s, bars %s, foos %s" % (self.id, self.data, repr([b for b in self.bars]), repr([f for f in self.foos])) + + Blub.mapper = mapper(Blub, blub, inherits=Bar.mapper, properties={ + 'bars':relation(Bar.mapper, blub_bar, primaryjoin=blub.c.id==blub_bar.c.blub_id, secondaryjoin=blub_bar.c.bar_id==bar.c.id, lazy=False), + 'foos':relation(Foo.mapper, blub_foo, primaryjoin=blub.c.id==blub_foo.c.blub_id, secondaryjoin=blub_foo.c.foo_id==foo.c.id, lazy=False), + }) + + useobjects = True + if (useobjects): + f1 = Foo("foo #1") + b1 = Bar("bar #1") + b2 = Bar("bar #2") + bl1 = Blub("blub #1") + bl1.foos.append(f1) + bl1.bars.append(b2) + objectstore.commit() + compare = repr(bl1) + blubid = bl1.id + objectstore.clear() + else: + foo.insert().execute(data='foo #1') + foo.insert().execute(data='foo #2') + bar.insert().execute(id=1, data="bar #1") + bar.insert().execute(id=2, data="bar #2") + blub.insert().execute(id=1, data="blub #1") + blub_bar.insert().execute(blub_id=1, bar_id=2) + blub_foo.insert().execute(blub_id=1, foo_id=2) + + l = Blub.mapper.select() + for x in l: + print x + + self.assert_(repr(l[0]) == compare) + objectstore.clear() + x = Blub.mapper.get_by(id=blubid) #traceback 2 + self.assert_(repr(x) == compare) + + </ins><span class="cx"> if __name__ == "__main__": </span><span class="cx"> testbase.main() </span></span></pre></div> <a id="sqlalchemytrunktestselectpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/select.py (1111 => 1112)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/select.py 2006-03-08 01:18:26 UTC (rev 1111) +++ sqlalchemy/trunk/test/select.py 2006-03-08 20:51:51 UTC (rev 1112) </span><span class="lines">@@ -418,7 +418,7 @@ </span><span class="cx"> select([s, table1]) </span><span class="cx"> ,"SELECT sq2.myid, sq2.name, sq2.description, mytable.myid, mytable.name, mytable.description FROM (SELECT ta.myid AS myid, ta.name AS name, ta.description AS description FROM mytable AS ta WHERE EXISTS (SELECT 1 FROM myothertable WHERE myothertable.otherid = ta.myid)) AS sq2, mytable") </span><span class="cx"> </span><del>- s = select([addresses.c.street], addresses.c.user_id==users.c.user_id).alias('s') </del><ins>+ s = select([addresses.c.street], addresses.c.user_id==users.c.user_id, correlate=True).alias('s') </ins><span class="cx"> self.runtest( </span><span class="cx"> select([users, s.c.street], from_obj=[s]), </span><span class="cx"> """SELECT users.user_id, users.user_name, users.password, s.street FROM users, (SELECT addresses.street AS street FROM addresses WHERE addresses.user_id = users.user_id) AS s""") </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-08 01:18:41
|
<!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>[1111] sqlalchemy/trunk/lib/sqlalchemy/sql.py: took erroneous 'count' off Alias</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1111</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-07 19:18:26 -0600 (Tue, 07 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>took erroneous 'count' off Alias</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemysqlpy">sqlalchemy/trunk/lib/sqlalchemy/sql.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/sql.py (1110 => 1111)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-07 05:46:36 UTC (rev 1110) +++ sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-03-08 01:18:26 UTC (rev 1111) </span><span class="lines">@@ -923,7 +923,6 @@ </span><span class="cx"> alias = n + "_" + hex(random.randint(0, 65535))[2:] </span><span class="cx"> self.name = alias </span><span class="cx"> self.id = self.name </span><del>- self.count = 0 </del><span class="cx"> if self.selectable.oid_column is not None: </span><span class="cx"> self.oid_column = self.selectable.oid_column._make_proxy(self) </span><span class="cx"> else: </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-07 05:46:46
|
<!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>[1110] sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py: took excess visit_func out, handled by ansisql compiler</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1110</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-06 23:46:36 -0600 (Mon, 06 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>took excess visit_func out, handled by ansisql compiler</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemydatabasesmysqlpy">sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemydatabasesmysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py (1109 => 1110)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py 2006-03-07 03:17:34 UTC (rev 1109) +++ sqlalchemy/trunk/lib/sqlalchemy/databases/mysql.py 2006-03-07 05:46:36 UTC (rev 1110) </span><span class="lines">@@ -232,12 +232,6 @@ </span><span class="cx"> </span><span class="cx"> class MySQLCompiler(ansisql.ANSICompiler): </span><span class="cx"> </span><del>- def visit_function(self, func): - if len(func.clauses): - super(MySQLCompiler, self).visit_function(func) - else: - self.strings[func] = func.name - </del><span class="cx"> def limit_clause(self, select): </span><span class="cx"> text = "" </span><span class="cx"> if select.limit is not None: </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-07 03:17:42
|
<!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>[1109] sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py: comment</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1109</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-06 21:17:34 -0600 (Mon, 06 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>comment</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemymappingpropertiespy">sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemymappingpropertiespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py (1108 => 1109)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-07 03:16:10 UTC (rev 1108) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-07 03:17:34 UTC (rev 1109) </span><span class="lines">@@ -806,12 +806,14 @@ </span><span class="cx"> mapper.set_property(key, class_(**kwargs )) </span><span class="cx"> </span><span class="cx"> class BackRef(object): </span><del>- """stores the name of a backreference property as well as a relation (PropertyLoader), - used to construct more customized backrefs""" </del><ins>+ """stores the name of a backreference property as well as options to + be used on the resulting PropertyLoader.""" </ins><span class="cx"> def __init__(self, key, **kwargs): </span><span class="cx"> self.key = key </span><span class="cx"> self.kwargs = kwargs </span><span class="cx"> def compile(self, prop): </span><ins>+ """called by the owning PropertyLoader to set up a backreference on the + PropertyLoader's mapper.""" </ins><span class="cx"> # try to set a LazyLoader on our mapper referencing the parent mapper </span><span class="cx"> if not prop.mapper.props.has_key(self.key): </span><span class="cx"> if prop.secondaryjoin is not None: </span><span class="lines">@@ -833,8 +835,8 @@ </span><span class="cx"> # else set one of us as the "backreference" </span><span class="cx"> if not prop.mapper.props[self.key].is_backref: </span><span class="cx"> prop.is_backref=True </span><del>- </del><span class="cx"> def get_extension(self): </span><ins>+ """returns an attribute extension to use with this backreference.""" </ins><span class="cx"> return attributes.GenericBackrefExtension(self.key) </span><span class="cx"> </span><span class="cx"> class EagerLazyOption(GenericOption): </span></span></pre> </div> </div> </body> </html> |
From: <co...@sq...> - 2006-03-07 03:16:20
|
<!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>[1108] sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py: backref() func will also honor lazy=True/False</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1108</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-03-06 21:16:10 -0600 (Mon, 06 Mar 2006)</dd> </dl> <h3>Log Message</h3> <pre>backref() func will also honor lazy=True/False</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemymappingpropertiespy">sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemymappingpropertiespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py (1107 => 1108)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-07 03:14:08 UTC (rev 1107) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/properties.py 2006-03-07 03:16:10 UTC (rev 1108) </span><span class="lines">@@ -822,7 +822,12 @@ </span><span class="cx"> else: </span><span class="cx"> pj = prop.primaryjoin </span><span class="cx"> sj = None </span><del>- relation = LazyLoader(prop.parent, prop.secondary, pj, sj, backref=prop.key, is_backref=True, **self.kwargs) </del><ins>+ lazy = self.kwargs.pop('lazy', True) + if lazy: + cls = LazyLoader + else: + cls = EagerLoader + relation = cls(prop.parent, prop.secondary, pj, sj, backref=prop.key, is_backref=True, **self.kwargs) </ins><span class="cx"> prop.mapper.add_property(self.key, relation); </span><span class="cx"> else: </span><span class="cx"> # else set one of us as the "backreference" </span></span></pre> </div> </div> </body> </html> |