sqlobject-cvs Mailing List for SQLObject (Page 136)
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
You can subscribe to this list here.
| 2003 |
Jan
|
Feb
|
Mar
(9) |
Apr
(74) |
May
(29) |
Jun
(16) |
Jul
(28) |
Aug
(10) |
Sep
(57) |
Oct
(9) |
Nov
(29) |
Dec
(12) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(7) |
Feb
(14) |
Mar
(6) |
Apr
(3) |
May
(12) |
Jun
(34) |
Jul
(9) |
Aug
(29) |
Sep
(22) |
Oct
(2) |
Nov
(15) |
Dec
(52) |
| 2005 |
Jan
(47) |
Feb
(78) |
Mar
(14) |
Apr
(35) |
May
(33) |
Jun
(16) |
Jul
(26) |
Aug
(63) |
Sep
(40) |
Oct
(96) |
Nov
(96) |
Dec
(123) |
| 2006 |
Jan
(159) |
Feb
(144) |
Mar
(64) |
Apr
(31) |
May
(88) |
Jun
(48) |
Jul
(16) |
Aug
(64) |
Sep
(87) |
Oct
(92) |
Nov
(56) |
Dec
(76) |
| 2007 |
Jan
(94) |
Feb
(103) |
Mar
(126) |
Apr
(123) |
May
(85) |
Jun
(11) |
Jul
(130) |
Aug
(47) |
Sep
(65) |
Oct
(70) |
Nov
(12) |
Dec
(11) |
| 2008 |
Jan
(30) |
Feb
(55) |
Mar
(88) |
Apr
(20) |
May
(50) |
Jun
|
Jul
(38) |
Aug
(1) |
Sep
(9) |
Oct
(5) |
Nov
(6) |
Dec
(39) |
| 2009 |
Jan
(8) |
Feb
(16) |
Mar
(3) |
Apr
(33) |
May
(44) |
Jun
(1) |
Jul
(10) |
Aug
(33) |
Sep
(74) |
Oct
(22) |
Nov
|
Dec
(15) |
| 2010 |
Jan
(28) |
Feb
(22) |
Mar
(46) |
Apr
(29) |
May
(1) |
Jun
(1) |
Jul
(27) |
Aug
(8) |
Sep
(5) |
Oct
(33) |
Nov
(24) |
Dec
(41) |
| 2011 |
Jan
(4) |
Feb
(12) |
Mar
(35) |
Apr
(29) |
May
(19) |
Jun
(16) |
Jul
(32) |
Aug
(25) |
Sep
(5) |
Oct
(11) |
Nov
(21) |
Dec
(12) |
| 2012 |
Jan
(3) |
Feb
(4) |
Mar
(20) |
Apr
(4) |
May
(25) |
Jun
(13) |
Jul
|
Aug
|
Sep
(2) |
Oct
(25) |
Nov
(9) |
Dec
(1) |
| 2013 |
Jan
(6) |
Feb
(8) |
Mar
|
Apr
(10) |
May
(31) |
Jun
(7) |
Jul
(18) |
Aug
(33) |
Sep
(4) |
Oct
(16) |
Nov
|
Dec
(27) |
| 2014 |
Jan
(2) |
Feb
|
Mar
|
Apr
(11) |
May
(39) |
Jun
(8) |
Jul
(11) |
Aug
(4) |
Sep
|
Oct
(27) |
Nov
|
Dec
(71) |
| 2015 |
Jan
(17) |
Feb
(47) |
Mar
(33) |
Apr
|
May
|
Jun
(9) |
Jul
(7) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(8) |
| 2016 |
Jan
(4) |
Feb
(4) |
Mar
|
Apr
|
May
(12) |
Jun
(7) |
Jul
(9) |
Aug
(31) |
Sep
(8) |
Oct
(3) |
Nov
(15) |
Dec
(1) |
| 2017 |
Jan
(13) |
Feb
(7) |
Mar
(14) |
Apr
(8) |
May
(10) |
Jun
(4) |
Jul
(2) |
Aug
(1) |
Sep
|
Oct
(8) |
Nov
(4) |
Dec
(5) |
| 2018 |
Jan
(2) |
Feb
(8) |
Mar
|
Apr
(4) |
May
|
Jun
(6) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2019 |
Jan
(1) |
Feb
(16) |
Mar
(1) |
Apr
(3) |
May
(5) |
Jun
(1) |
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
(3) |
| 2020 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
(2) |
Nov
|
Dec
(2) |
| 2021 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2022 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(6) |
Oct
(1) |
Nov
(1) |
Dec
(4) |
| 2023 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(3) |
Sep
(2) |
Oct
(2) |
Nov
(4) |
Dec
|
| 2024 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(9) |
| 2025 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(2) |
Dec
(2) |
|
From: SourceForge.net <no...@so...> - 2006-02-17 12:38:25
|
Patches item #1353728, was opened at 2005-11-11 10:20 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: define foreign keys in Style Initial Comment: I don't like to use attrID all along the code to access related tables, I want to be able use the nomeclature I like taking advantage of the nice Style idea. This is especially true when you create RelatedJoins when you use a nomeclature like I do (table.id_table), but it's the same for all the nomeclatures you can imagine. In styles.py it warns: def instanceAttrToIDAttr(self, attr): # @@: Right now, because of how names are created for foreign # keys, you can't really change this style. return attr + "ID" With this patch you can define how you want the foreign keys generated, they won't be mandatorily generated as attrID. Example: class LongStyle(Style): """ This style is derived from Style, that does not do any translation, but constructs the table ids like id_table. """ def instanceAttrToIDAttr(self, attr): return "id_" + attr def tableReference(self, table): # str.rsplit is python 2.4+ only if version_info >= (2, 4): return "id_" + table.rsplit(".", 1)[-1] else: return "id_" + rsplit(table, ".", 1)[-1] class mm_server(SQLObject): class sqlmeta: table = "smsarena.mm_server" style = LongStyle(longID = True) _connection = conn_smsarena server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") tz = StringCol(length = 20, default = 'CET', notNone = True) conutry_code = StringCol(length = 2, varchar = False, default = '', notNone = True) # until now I had to do this # mm_server_aliases = SQLMultipleJoin("mm_server_alias", joinColumn = "mm_serverID", orderBy = "server") # now it's perfect! mm_server_aliases = SQLMultipleJoin("mm_server_alias", orderBy = "server") class mm_server_alias(SQLObject): class sqlmeta: table = "smsarena.mm_server_alias" style = LongStyle(longID = True) _connection = conn_smsarena # until now I had to do this # mm_server = ForeignKey("mm_server", dbName = "id_mm_server") mm_server = ForeignKey("mm_server") server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") I hope it's clear :) Pau ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-02-17 15:38 Message: Logged In: YES user_id=4799 Except for the problem i test_ForeignKey.py that I know about... others look pretty strange. Let look at the environment. What DB versions? MySQL, PgSQL, SQLite? Drivers versions? MySQLdb, psycopg, PySQLite? MyPostgres is 7.4, psycopg 1.1.21 and 2.0b5. PySQLite 1.1.7 and 2.1.3. A week ago I upgarded to SQLite 3.3.3 and PySQLite 2.1.3; that eliminated some minor problems with patches I have had with SQLIte 2.8.0 and PySQLite 2.1.0. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-17 15:11 Message: Logged In: YES user_id=140558 Ok, plain SQLObject from SVN now, no patch. There are tests that fail for me in current SQLObject in mysql, postgres and sqlite. I attach them all. This is a fully updated Fedora 4. I've made the tests in mysql and there are some thet do not pass. I enclose the results and a file where I comment why the fail and a possible solution. The tests that fail in postgres and sqlite are the ones I've already reported (mnore or less). Any help? ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-17 12:22 Message: Logged In: YES user_id=4799 No, the latest SQLObject passes all tests (how would I commit your other patch if a test fail?) except for minor glitch in test_ForeignKey.py which I'm going to resolve RSN. test_auto.py certainly pass. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-17 12:13 Message: Logged In: YES user_id=140558 I've run the test with the latest SQLObject (no extra patches) and the tests fail too, at least they fail when I run them. As I explained before, there's something wrong when adding columns to sqlite, it fails and all the tests that depend on the added columns fail too. Does it happen to you too? ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-16 18:16 Message: Logged In: YES user_id=4799 These tests fail in both Postgres and SQLite. Two major backends (of 3) for SQLObject. If the problem is in tests you can patch tests, too... test_auto.py: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] > l = [p.phone for p in Person.selectBy(name='tim')[0].phones] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/test_auto.py:59] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > [failure to get at sourcelines from <TracebackEntry /home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1>] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def performJoin(self, inst): ids = inst._connection._SO_selectJoin( self.otherClass, self.joinColumn, > inst.id) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/joins.py:144] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _SO_selectJoin(self, soClass, column, value): return self.queryAll("SELECT %s FROM %s WHERE %s = %s" % (soClass.sqlmeta.idName, soClass.sqlmeta.table, column, > self.sqlrepr(value))) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:652] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def queryAll(self, s): > return self._runWithConnection(self._queryAll, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:327] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _runWithConnection(self, meth, *args): conn = self.getConnection() try: > val = meth(conn, *args) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:228] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _queryAll(self, conn, s): if self.debug: self.printDebug(conn, s, 'QueryAll') c = conn.cursor() > self._executeRetry(conn, c, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:320] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _executeRetry(self, conn, cursor, query): if self.debug: self.printDebug(conn, query, 'QueryR') E return cursor.execute(query) > OperationalError: no such column: person_id [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:306] - - - - - - - - - - - test_dynamicJoin: recorded stdout - - - - - - - - - - - 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/Query : DELETE FROM person 1/QueryR : DELETE FROM person 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/Query : DELETE FROM phone 1/QueryR : DELETE FROM phone 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jane') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 1 1/QueryR : SELECT name_col FROM person WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('tim') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 2 1/QueryR : SELECT name_col FROM person WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('bob') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 3 1/QueryR : SELECT name_col FROM person WHERE id = 3 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jake') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 4 1/QueryR : SELECT name_col FROM person WHERE id = 4 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-555-5555') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 1 1/QueryR : SELECT phone FROM phone WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-394-2930') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 2 1/QueryR : SELECT phone FROM phone WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('444-382-4854') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 3 1/QueryR : SELECT phone FROM phone WHERE id = 3 1/COMMIT : auto 1/Query : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/QueryR : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/COMMIT : auto 1/Select : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/QueryR : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/QueryAll: SELECT id FROM phone WHERE person_id = 2 1/QueryR : SELECT id FROM phone WHERE person_id = 2 1/COMMIT : auto ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 18:54 Message: Logged In: YES user_id=140558 Ok, here I go again. I've fixed a small bug: the name of the field was not porperly set when using Key(foreignKey... instead of ForeignKey. This fixes test_basic. And I think that there is nothing else to fix, I'm probably wrong, but I'll explain it hera. test_auto_old.py... FAIL test_auto.py... FAIL test_foreignKey.py... FAIL These tests fail because sqlite is failing when adding columns. In mysql it does not fail. I do not think it's this patch fault. And finally: test_SQLMultipleJoin.py... FAIL E assert str(hibrid.fightersAsSResult.sum('power')) == '23' > assert '23.0' == '23' + where '23.0' = str(23.0) + where 23.0 = <Race 3 name="'hibrid (human wi...'">.fightersAsSResult.sum('power') Again this is an error in the test. Please let me know if it can go in now :) If you can have a quick look at it better, it takes time to restart ths tests, I'd rather do it before I move on to another thing. Thanks Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-14 12:05 Message: Logged In: YES user_id=140558 Oleg, I've posted to the list because I run the tests and pass. I'm sure I'm doing something wrong but I don't see what. I lost more than 3 hours yesterday just trying to run te tests :( I printed things in dbtest.py and say that TESTDB did not change anything. I chenged manually conftest.py because I ahd a message that yoiu need sqlite2 for memory databases, but still I'm not sure everything works becasue I pass al the tests. Can you help me, I want to close this patch soon and move to other improvements but this is being much more difficult than it should. Thanks a lot Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-09 19:42 Message: Logged In: YES user_id=140558 I'm very busy but again will try to find some time to fix it. I'm using it every day without a glitch, even using the clause attributes like in the Complex example (new type of joins *toMany). I'll update it to latest SVN just in case this is the problem, I did it with that day's current. Please do not close it, I really intend to pass the tests, I'm already using it. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-09 19:11 Message: Logged In: YES user_id=4799 test_auto.py, for example fails: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] l = [p.phone for p in Person.selectBy(name='tim')[0].phones] l.sort() E assert l == ['555-394-2930', '555-555-5555'] > assert [] == ['555-394-2930', '555-555-5555'] [sqlobject/tests/test_auto.py:61] ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 21:10 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 21:07 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-30 20:57 Message: Logged In: YES user_id=4799 test_auto.py, test_auto_old.py and test_basic.py failed. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 19:04 Message: Logged In: YES user_id=140558 This is the final patch against latest svn, it includes everything in one single patch. It passes the tests. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 16:17 Message: Logged In: YES user_id=140558 Ok, I have taken my time to understand pydist, test, etc, and here I am back with the working solution :) Now the resulting SQLobject passes all the tests. I attach an incremental patch so that you can see more clearly the changes done to fix the previous one. I've needed a new method in the Style class, instanceIDAttrToAttr, that is the complementary to the already known instanceAttrToIDAttr. If you need to transform back and forth field names, you need them both. I haven't tried to port it to the latest svn yet, this is against the same release than the first patch, but it should apply more or less clearly as this are very isolated areas in the code. When I do it I'll post it here. Sorry for the delay, it has not been easy for me to understand more deeply the code and, even less, to know how the tests work :) ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-03 15:18 Message: Logged In: YES user_id=140558 It fails because the test is not right, it still has the ID postfix hardcoded. My fault, I did no send a patch for tests. This is the piece that fails: # Select by usual way s = TestWorkKey.selectBy(composerID=c.id, title='Symphony No. 9') I have not looked at tests until now, but it looks like there should be tests for the different provides styles, in this case, if you accept the patch, at least a test for the LongStyle provided and for the current naming styles. I'll try to cook up something, but it can take a little time. Any guidelines will be appreciated (I've just read the docs ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-03 14:23 Message: Logged In: YES user_id=4799 test_selectBy_foreignKey.py fails: def test1(): setupClass([TestComposerKey, TestWorkKey]) c = TestComposerKey(name='Mahler, Gustav') > w1 = TestWorkKey(composer=c, title='Symphony No. 9') [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/tests/test_selectBy_foreignKey.py:19] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def __init__(self, **kw): # The get() classmethod/constructor uses a magic keyword # argument when it wants an empty object, fetched from the # database. So we have nothing more to do in that case: if kw.has_key('_SO_fetch_no_create'): return post_funcs = [] self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) # Pass the connection object along if we were given one. if kw.has_key('connection'): self._connection = kw['connection'] self.sqlmeta._perConnection = True del kw['connection'] self._SO_writeLock = threading.Lock() if kw.has_key('id'): id = self.sqlmeta.idType(kw['id']) del kw['id'] else: id = None > self._create(id, **kw) [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1210] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _create(self, id, **kw): self.sqlmeta._creating = True self._SO_createValues = {} self._SO_validatorState = SQLObjectState(self) # First we do a little fix-up on the keywords we were # passed: for column in self.sqlmeta.columnList: # Then we check if the column wasn't passed in, and # if not we try to get the default. if not kw.has_key(column.name) and not kw.has_key(column.foreignName): default = column.default # If we don't get it, it's an error: if default is NoDefault: E raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, column.name) > TypeError: TestWorkKey() did not get expected keyword argument composerID [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1231] - - - - - - - - - - - - - test1: recorded stdout - - - - - - - - - - - - - - 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/QueryR : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/QueryR : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/COMMIT : auto 1/Query : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/QueryR : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/COMMIT : auto 1/QueryIns: INSERT INTO test_composer_key (id, name) VALUES (1, 'Mahler, Gustav') 1/COMMIT : auto 1/QueryOne: SELECT name FROM test_composer_key WHERE id = 1 1/QueryR : SELECT name FROM test_composer_key WHERE id = 1 1/COMMIT : auto ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-17 12:11:15
|
Patches item #1353728, was opened at 2005-11-11 08:20 Message generated for change (Comment added) made by linux4u You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: define foreign keys in Style Initial Comment: I don't like to use attrID all along the code to access related tables, I want to be able use the nomeclature I like taking advantage of the nice Style idea. This is especially true when you create RelatedJoins when you use a nomeclature like I do (table.id_table), but it's the same for all the nomeclatures you can imagine. In styles.py it warns: def instanceAttrToIDAttr(self, attr): # @@: Right now, because of how names are created for foreign # keys, you can't really change this style. return attr + "ID" With this patch you can define how you want the foreign keys generated, they won't be mandatorily generated as attrID. Example: class LongStyle(Style): """ This style is derived from Style, that does not do any translation, but constructs the table ids like id_table. """ def instanceAttrToIDAttr(self, attr): return "id_" + attr def tableReference(self, table): # str.rsplit is python 2.4+ only if version_info >= (2, 4): return "id_" + table.rsplit(".", 1)[-1] else: return "id_" + rsplit(table, ".", 1)[-1] class mm_server(SQLObject): class sqlmeta: table = "smsarena.mm_server" style = LongStyle(longID = True) _connection = conn_smsarena server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") tz = StringCol(length = 20, default = 'CET', notNone = True) conutry_code = StringCol(length = 2, varchar = False, default = '', notNone = True) # until now I had to do this # mm_server_aliases = SQLMultipleJoin("mm_server_alias", joinColumn = "mm_serverID", orderBy = "server") # now it's perfect! mm_server_aliases = SQLMultipleJoin("mm_server_alias", orderBy = "server") class mm_server_alias(SQLObject): class sqlmeta: table = "smsarena.mm_server_alias" style = LongStyle(longID = True) _connection = conn_smsarena # until now I had to do this # mm_server = ForeignKey("mm_server", dbName = "id_mm_server") mm_server = ForeignKey("mm_server") server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") I hope it's clear :) Pau ---------------------------------------------------------------------- >Comment By: Pau Aliagas (linux4u) Date: 2006-02-17 13:11 Message: Logged In: YES user_id=140558 Ok, plain SQLObject from SVN now, no patch. There are tests that fail for me in current SQLObject in mysql, postgres and sqlite. I attach them all. This is a fully updated Fedora 4. I've made the tests in mysql and there are some thet do not pass. I enclose the results and a file where I comment why the fail and a possible solution. The tests that fail in postgres and sqlite are the ones I've already reported (mnore or less). Any help? ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-17 10:22 Message: Logged In: YES user_id=4799 No, the latest SQLObject passes all tests (how would I commit your other patch if a test fail?) except for minor glitch in test_ForeignKey.py which I'm going to resolve RSN. test_auto.py certainly pass. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-17 10:13 Message: Logged In: YES user_id=140558 I've run the test with the latest SQLObject (no extra patches) and the tests fail too, at least they fail when I run them. As I explained before, there's something wrong when adding columns to sqlite, it fails and all the tests that depend on the added columns fail too. Does it happen to you too? ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-16 16:16 Message: Logged In: YES user_id=4799 These tests fail in both Postgres and SQLite. Two major backends (of 3) for SQLObject. If the problem is in tests you can patch tests, too... test_auto.py: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] > l = [p.phone for p in Person.selectBy(name='tim')[0].phones] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/test_auto.py:59] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > [failure to get at sourcelines from <TracebackEntry /home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1>] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def performJoin(self, inst): ids = inst._connection._SO_selectJoin( self.otherClass, self.joinColumn, > inst.id) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/joins.py:144] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _SO_selectJoin(self, soClass, column, value): return self.queryAll("SELECT %s FROM %s WHERE %s = %s" % (soClass.sqlmeta.idName, soClass.sqlmeta.table, column, > self.sqlrepr(value))) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:652] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def queryAll(self, s): > return self._runWithConnection(self._queryAll, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:327] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _runWithConnection(self, meth, *args): conn = self.getConnection() try: > val = meth(conn, *args) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:228] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _queryAll(self, conn, s): if self.debug: self.printDebug(conn, s, 'QueryAll') c = conn.cursor() > self._executeRetry(conn, c, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:320] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _executeRetry(self, conn, cursor, query): if self.debug: self.printDebug(conn, query, 'QueryR') E return cursor.execute(query) > OperationalError: no such column: person_id [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:306] - - - - - - - - - - - test_dynamicJoin: recorded stdout - - - - - - - - - - - 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/Query : DELETE FROM person 1/QueryR : DELETE FROM person 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/Query : DELETE FROM phone 1/QueryR : DELETE FROM phone 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jane') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 1 1/QueryR : SELECT name_col FROM person WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('tim') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 2 1/QueryR : SELECT name_col FROM person WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('bob') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 3 1/QueryR : SELECT name_col FROM person WHERE id = 3 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jake') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 4 1/QueryR : SELECT name_col FROM person WHERE id = 4 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-555-5555') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 1 1/QueryR : SELECT phone FROM phone WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-394-2930') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 2 1/QueryR : SELECT phone FROM phone WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('444-382-4854') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 3 1/QueryR : SELECT phone FROM phone WHERE id = 3 1/COMMIT : auto 1/Query : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/QueryR : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/COMMIT : auto 1/Select : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/QueryR : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/QueryAll: SELECT id FROM phone WHERE person_id = 2 1/QueryR : SELECT id FROM phone WHERE person_id = 2 1/COMMIT : auto ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 16:54 Message: Logged In: YES user_id=140558 Ok, here I go again. I've fixed a small bug: the name of the field was not porperly set when using Key(foreignKey... instead of ForeignKey. This fixes test_basic. And I think that there is nothing else to fix, I'm probably wrong, but I'll explain it hera. test_auto_old.py... FAIL test_auto.py... FAIL test_foreignKey.py... FAIL These tests fail because sqlite is failing when adding columns. In mysql it does not fail. I do not think it's this patch fault. And finally: test_SQLMultipleJoin.py... FAIL E assert str(hibrid.fightersAsSResult.sum('power')) == '23' > assert '23.0' == '23' + where '23.0' = str(23.0) + where 23.0 = <Race 3 name="'hibrid (human wi...'">.fightersAsSResult.sum('power') Again this is an error in the test. Please let me know if it can go in now :) If you can have a quick look at it better, it takes time to restart ths tests, I'd rather do it before I move on to another thing. Thanks Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-14 10:05 Message: Logged In: YES user_id=140558 Oleg, I've posted to the list because I run the tests and pass. I'm sure I'm doing something wrong but I don't see what. I lost more than 3 hours yesterday just trying to run te tests :( I printed things in dbtest.py and say that TESTDB did not change anything. I chenged manually conftest.py because I ahd a message that yoiu need sqlite2 for memory databases, but still I'm not sure everything works becasue I pass al the tests. Can you help me, I want to close this patch soon and move to other improvements but this is being much more difficult than it should. Thanks a lot Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-09 17:42 Message: Logged In: YES user_id=140558 I'm very busy but again will try to find some time to fix it. I'm using it every day without a glitch, even using the clause attributes like in the Complex example (new type of joins *toMany). I'll update it to latest SVN just in case this is the problem, I did it with that day's current. Please do not close it, I really intend to pass the tests, I'm already using it. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-09 17:11 Message: Logged In: YES user_id=4799 test_auto.py, for example fails: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] l = [p.phone for p in Person.selectBy(name='tim')[0].phones] l.sort() E assert l == ['555-394-2930', '555-555-5555'] > assert [] == ['555-394-2930', '555-555-5555'] [sqlobject/tests/test_auto.py:61] ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 19:10 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 19:07 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-30 18:57 Message: Logged In: YES user_id=4799 test_auto.py, test_auto_old.py and test_basic.py failed. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 17:04 Message: Logged In: YES user_id=140558 This is the final patch against latest svn, it includes everything in one single patch. It passes the tests. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 14:17 Message: Logged In: YES user_id=140558 Ok, I have taken my time to understand pydist, test, etc, and here I am back with the working solution :) Now the resulting SQLobject passes all the tests. I attach an incremental patch so that you can see more clearly the changes done to fix the previous one. I've needed a new method in the Style class, instanceIDAttrToAttr, that is the complementary to the already known instanceAttrToIDAttr. If you need to transform back and forth field names, you need them both. I haven't tried to port it to the latest svn yet, this is against the same release than the first patch, but it should apply more or less clearly as this are very isolated areas in the code. When I do it I'll post it here. Sorry for the delay, it has not been easy for me to understand more deeply the code and, even less, to know how the tests work :) ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-03 13:18 Message: Logged In: YES user_id=140558 It fails because the test is not right, it still has the ID postfix hardcoded. My fault, I did no send a patch for tests. This is the piece that fails: # Select by usual way s = TestWorkKey.selectBy(composerID=c.id, title='Symphony No. 9') I have not looked at tests until now, but it looks like there should be tests for the different provides styles, in this case, if you accept the patch, at least a test for the LongStyle provided and for the current naming styles. I'll try to cook up something, but it can take a little time. Any guidelines will be appreciated (I've just read the docs ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-03 12:23 Message: Logged In: YES user_id=4799 test_selectBy_foreignKey.py fails: def test1(): setupClass([TestComposerKey, TestWorkKey]) c = TestComposerKey(name='Mahler, Gustav') > w1 = TestWorkKey(composer=c, title='Symphony No. 9') [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/tests/test_selectBy_foreignKey.py:19] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def __init__(self, **kw): # The get() classmethod/constructor uses a magic keyword # argument when it wants an empty object, fetched from the # database. So we have nothing more to do in that case: if kw.has_key('_SO_fetch_no_create'): return post_funcs = [] self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) # Pass the connection object along if we were given one. if kw.has_key('connection'): self._connection = kw['connection'] self.sqlmeta._perConnection = True del kw['connection'] self._SO_writeLock = threading.Lock() if kw.has_key('id'): id = self.sqlmeta.idType(kw['id']) del kw['id'] else: id = None > self._create(id, **kw) [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1210] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _create(self, id, **kw): self.sqlmeta._creating = True self._SO_createValues = {} self._SO_validatorState = SQLObjectState(self) # First we do a little fix-up on the keywords we were # passed: for column in self.sqlmeta.columnList: # Then we check if the column wasn't passed in, and # if not we try to get the default. if not kw.has_key(column.name) and not kw.has_key(column.foreignName): default = column.default # If we don't get it, it's an error: if default is NoDefault: E raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, column.name) > TypeError: TestWorkKey() did not get expected keyword argument composerID [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1231] - - - - - - - - - - - - - test1: recorded stdout - - - - - - - - - - - - - - 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/QueryR : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/QueryR : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/COMMIT : auto 1/Query : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/QueryR : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/COMMIT : auto 1/QueryIns: INSERT INTO test_composer_key (id, name) VALUES (1, 'Mahler, Gustav') 1/COMMIT : auto 1/QueryOne: SELECT name FROM test_composer_key WHERE id = 1 1/QueryR : SELECT name FROM test_composer_key WHERE id = 1 1/COMMIT : auto ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 |
|
From: <sub...@co...> - 2006-02-17 10:11:26
|
Author: phd Date: 2006-02-17 03:11:19 -0700 (Fri, 17 Feb 2006) New Revision: 1606 Modified: SQLObject/branches/0.7-bugfix/docs/News.txt Log: Minor update. Modified: SQLObject/branches/0.7-bugfix/docs/News.txt =================================================================== --- SQLObject/branches/0.7-bugfix/docs/News.txt 2006-02-17 10:09:59 UTC (rev 1605) +++ SQLObject/branches/0.7-bugfix/docs/News.txt 2006-02-17 10:11:19 UTC (rev 1606) @@ -10,18 +10,24 @@ SQLObject 0.7.1 =============== -* Added ``TimeCol``. - * Added support for psycopg2_ .. _psycopg2: http://initd.org/projects/psycopg2 +* Added support for MSSQL_. + +.. _MSSQL: SQLObject.html#ms-sql-server + +* Added ``TimeCol``. + * ``RelatedJoin`` and ``SQLRelatedJoin`` objects have a ``createRelatedTable`` keyword argument (default ``True``). If ``False``, then the related table won't be automatically created; instead you must manually create it (e.g., with explicit SQLObject classes for the joins). +* Implemented ``RLIKE`` (reguluar expression LIKE). + SQLObject 0.7.0 =============== |
|
From: <sub...@co...> - 2006-02-17 10:10:14
|
Author: phd Date: 2006-02-17 03:09:59 -0700 (Fri, 17 Feb 2006) New Revision: 1605 Modified: SQLObject/docs/News.txt Log: Minor update. Modified: SQLObject/docs/News.txt =================================================================== --- SQLObject/docs/News.txt 2006-02-16 17:14:42 UTC (rev 1604) +++ SQLObject/docs/News.txt 2006-02-17 10:09:59 UTC (rev 1605) @@ -13,10 +13,6 @@ Features & Interface -------------------- -* Added support for MSSQL_. - -.. _MSSQL: SQLObject.html#ms-sql-server - * It is now possible to create tables that reference each other. Constraints (in the DBMSes that support constraints) are added after the tables have been created. @@ -64,6 +60,12 @@ .. _psycopg2: http://initd.org/projects/psycopg2 +* Added support for MSSQL_. + +.. _MSSQL: SQLObject.html#ms-sql-server + +* Implemented ``RLIKE`` (reguluar expression LIKE). + SQLObject 0.7.0 =============== |
|
From: SourceForge.net <no...@so...> - 2006-02-17 09:22:12
|
Patches item #1353728, was opened at 2005-11-11 10:20 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: define foreign keys in Style Initial Comment: I don't like to use attrID all along the code to access related tables, I want to be able use the nomeclature I like taking advantage of the nice Style idea. This is especially true when you create RelatedJoins when you use a nomeclature like I do (table.id_table), but it's the same for all the nomeclatures you can imagine. In styles.py it warns: def instanceAttrToIDAttr(self, attr): # @@: Right now, because of how names are created for foreign # keys, you can't really change this style. return attr + "ID" With this patch you can define how you want the foreign keys generated, they won't be mandatorily generated as attrID. Example: class LongStyle(Style): """ This style is derived from Style, that does not do any translation, but constructs the table ids like id_table. """ def instanceAttrToIDAttr(self, attr): return "id_" + attr def tableReference(self, table): # str.rsplit is python 2.4+ only if version_info >= (2, 4): return "id_" + table.rsplit(".", 1)[-1] else: return "id_" + rsplit(table, ".", 1)[-1] class mm_server(SQLObject): class sqlmeta: table = "smsarena.mm_server" style = LongStyle(longID = True) _connection = conn_smsarena server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") tz = StringCol(length = 20, default = 'CET', notNone = True) conutry_code = StringCol(length = 2, varchar = False, default = '', notNone = True) # until now I had to do this # mm_server_aliases = SQLMultipleJoin("mm_server_alias", joinColumn = "mm_serverID", orderBy = "server") # now it's perfect! mm_server_aliases = SQLMultipleJoin("mm_server_alias", orderBy = "server") class mm_server_alias(SQLObject): class sqlmeta: table = "smsarena.mm_server_alias" style = LongStyle(longID = True) _connection = conn_smsarena # until now I had to do this # mm_server = ForeignKey("mm_server", dbName = "id_mm_server") mm_server = ForeignKey("mm_server") server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") I hope it's clear :) Pau ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-02-17 12:22 Message: Logged In: YES user_id=4799 No, the latest SQLObject passes all tests (how would I commit your other patch if a test fail?) except for minor glitch in test_ForeignKey.py which I'm going to resolve RSN. test_auto.py certainly pass. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-17 12:13 Message: Logged In: YES user_id=140558 I've run the test with the latest SQLObject (no extra patches) and the tests fail too, at least they fail when I run them. As I explained before, there's something wrong when adding columns to sqlite, it fails and all the tests that depend on the added columns fail too. Does it happen to you too? ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-16 18:16 Message: Logged In: YES user_id=4799 These tests fail in both Postgres and SQLite. Two major backends (of 3) for SQLObject. If the problem is in tests you can patch tests, too... test_auto.py: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] > l = [p.phone for p in Person.selectBy(name='tim')[0].phones] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/test_auto.py:59] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > [failure to get at sourcelines from <TracebackEntry /home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1>] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def performJoin(self, inst): ids = inst._connection._SO_selectJoin( self.otherClass, self.joinColumn, > inst.id) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/joins.py:144] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _SO_selectJoin(self, soClass, column, value): return self.queryAll("SELECT %s FROM %s WHERE %s = %s" % (soClass.sqlmeta.idName, soClass.sqlmeta.table, column, > self.sqlrepr(value))) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:652] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def queryAll(self, s): > return self._runWithConnection(self._queryAll, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:327] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _runWithConnection(self, meth, *args): conn = self.getConnection() try: > val = meth(conn, *args) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:228] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _queryAll(self, conn, s): if self.debug: self.printDebug(conn, s, 'QueryAll') c = conn.cursor() > self._executeRetry(conn, c, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:320] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _executeRetry(self, conn, cursor, query): if self.debug: self.printDebug(conn, query, 'QueryR') E return cursor.execute(query) > OperationalError: no such column: person_id [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:306] - - - - - - - - - - - test_dynamicJoin: recorded stdout - - - - - - - - - - - 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/Query : DELETE FROM person 1/QueryR : DELETE FROM person 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/Query : DELETE FROM phone 1/QueryR : DELETE FROM phone 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jane') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 1 1/QueryR : SELECT name_col FROM person WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('tim') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 2 1/QueryR : SELECT name_col FROM person WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('bob') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 3 1/QueryR : SELECT name_col FROM person WHERE id = 3 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jake') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 4 1/QueryR : SELECT name_col FROM person WHERE id = 4 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-555-5555') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 1 1/QueryR : SELECT phone FROM phone WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-394-2930') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 2 1/QueryR : SELECT phone FROM phone WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('444-382-4854') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 3 1/QueryR : SELECT phone FROM phone WHERE id = 3 1/COMMIT : auto 1/Query : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/QueryR : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/COMMIT : auto 1/Select : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/QueryR : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/QueryAll: SELECT id FROM phone WHERE person_id = 2 1/QueryR : SELECT id FROM phone WHERE person_id = 2 1/COMMIT : auto ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 18:54 Message: Logged In: YES user_id=140558 Ok, here I go again. I've fixed a small bug: the name of the field was not porperly set when using Key(foreignKey... instead of ForeignKey. This fixes test_basic. And I think that there is nothing else to fix, I'm probably wrong, but I'll explain it hera. test_auto_old.py... FAIL test_auto.py... FAIL test_foreignKey.py... FAIL These tests fail because sqlite is failing when adding columns. In mysql it does not fail. I do not think it's this patch fault. And finally: test_SQLMultipleJoin.py... FAIL E assert str(hibrid.fightersAsSResult.sum('power')) == '23' > assert '23.0' == '23' + where '23.0' = str(23.0) + where 23.0 = <Race 3 name="'hibrid (human wi...'">.fightersAsSResult.sum('power') Again this is an error in the test. Please let me know if it can go in now :) If you can have a quick look at it better, it takes time to restart ths tests, I'd rather do it before I move on to another thing. Thanks Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-14 12:05 Message: Logged In: YES user_id=140558 Oleg, I've posted to the list because I run the tests and pass. I'm sure I'm doing something wrong but I don't see what. I lost more than 3 hours yesterday just trying to run te tests :( I printed things in dbtest.py and say that TESTDB did not change anything. I chenged manually conftest.py because I ahd a message that yoiu need sqlite2 for memory databases, but still I'm not sure everything works becasue I pass al the tests. Can you help me, I want to close this patch soon and move to other improvements but this is being much more difficult than it should. Thanks a lot Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-09 19:42 Message: Logged In: YES user_id=140558 I'm very busy but again will try to find some time to fix it. I'm using it every day without a glitch, even using the clause attributes like in the Complex example (new type of joins *toMany). I'll update it to latest SVN just in case this is the problem, I did it with that day's current. Please do not close it, I really intend to pass the tests, I'm already using it. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-09 19:11 Message: Logged In: YES user_id=4799 test_auto.py, for example fails: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] l = [p.phone for p in Person.selectBy(name='tim')[0].phones] l.sort() E assert l == ['555-394-2930', '555-555-5555'] > assert [] == ['555-394-2930', '555-555-5555'] [sqlobject/tests/test_auto.py:61] ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 21:10 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 21:07 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-30 20:57 Message: Logged In: YES user_id=4799 test_auto.py, test_auto_old.py and test_basic.py failed. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 19:04 Message: Logged In: YES user_id=140558 This is the final patch against latest svn, it includes everything in one single patch. It passes the tests. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 16:17 Message: Logged In: YES user_id=140558 Ok, I have taken my time to understand pydist, test, etc, and here I am back with the working solution :) Now the resulting SQLobject passes all the tests. I attach an incremental patch so that you can see more clearly the changes done to fix the previous one. I've needed a new method in the Style class, instanceIDAttrToAttr, that is the complementary to the already known instanceAttrToIDAttr. If you need to transform back and forth field names, you need them both. I haven't tried to port it to the latest svn yet, this is against the same release than the first patch, but it should apply more or less clearly as this are very isolated areas in the code. When I do it I'll post it here. Sorry for the delay, it has not been easy for me to understand more deeply the code and, even less, to know how the tests work :) ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-03 15:18 Message: Logged In: YES user_id=140558 It fails because the test is not right, it still has the ID postfix hardcoded. My fault, I did no send a patch for tests. This is the piece that fails: # Select by usual way s = TestWorkKey.selectBy(composerID=c.id, title='Symphony No. 9') I have not looked at tests until now, but it looks like there should be tests for the different provides styles, in this case, if you accept the patch, at least a test for the LongStyle provided and for the current naming styles. I'll try to cook up something, but it can take a little time. Any guidelines will be appreciated (I've just read the docs ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-03 14:23 Message: Logged In: YES user_id=4799 test_selectBy_foreignKey.py fails: def test1(): setupClass([TestComposerKey, TestWorkKey]) c = TestComposerKey(name='Mahler, Gustav') > w1 = TestWorkKey(composer=c, title='Symphony No. 9') [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/tests/test_selectBy_foreignKey.py:19] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def __init__(self, **kw): # The get() classmethod/constructor uses a magic keyword # argument when it wants an empty object, fetched from the # database. So we have nothing more to do in that case: if kw.has_key('_SO_fetch_no_create'): return post_funcs = [] self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) # Pass the connection object along if we were given one. if kw.has_key('connection'): self._connection = kw['connection'] self.sqlmeta._perConnection = True del kw['connection'] self._SO_writeLock = threading.Lock() if kw.has_key('id'): id = self.sqlmeta.idType(kw['id']) del kw['id'] else: id = None > self._create(id, **kw) [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1210] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _create(self, id, **kw): self.sqlmeta._creating = True self._SO_createValues = {} self._SO_validatorState = SQLObjectState(self) # First we do a little fix-up on the keywords we were # passed: for column in self.sqlmeta.columnList: # Then we check if the column wasn't passed in, and # if not we try to get the default. if not kw.has_key(column.name) and not kw.has_key(column.foreignName): default = column.default # If we don't get it, it's an error: if default is NoDefault: E raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, column.name) > TypeError: TestWorkKey() did not get expected keyword argument composerID [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1231] - - - - - - - - - - - - - test1: recorded stdout - - - - - - - - - - - - - - 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/QueryR : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/QueryR : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/COMMIT : auto 1/Query : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/QueryR : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/COMMIT : auto 1/QueryIns: INSERT INTO test_composer_key (id, name) VALUES (1, 'Mahler, Gustav') 1/COMMIT : auto 1/QueryOne: SELECT name FROM test_composer_key WHERE id = 1 1/QueryR : SELECT name FROM test_composer_key WHERE id = 1 1/COMMIT : auto ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-17 09:13:56
|
Patches item #1353728, was opened at 2005-11-11 08:20 Message generated for change (Comment added) made by linux4u You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: define foreign keys in Style Initial Comment: I don't like to use attrID all along the code to access related tables, I want to be able use the nomeclature I like taking advantage of the nice Style idea. This is especially true when you create RelatedJoins when you use a nomeclature like I do (table.id_table), but it's the same for all the nomeclatures you can imagine. In styles.py it warns: def instanceAttrToIDAttr(self, attr): # @@: Right now, because of how names are created for foreign # keys, you can't really change this style. return attr + "ID" With this patch you can define how you want the foreign keys generated, they won't be mandatorily generated as attrID. Example: class LongStyle(Style): """ This style is derived from Style, that does not do any translation, but constructs the table ids like id_table. """ def instanceAttrToIDAttr(self, attr): return "id_" + attr def tableReference(self, table): # str.rsplit is python 2.4+ only if version_info >= (2, 4): return "id_" + table.rsplit(".", 1)[-1] else: return "id_" + rsplit(table, ".", 1)[-1] class mm_server(SQLObject): class sqlmeta: table = "smsarena.mm_server" style = LongStyle(longID = True) _connection = conn_smsarena server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") tz = StringCol(length = 20, default = 'CET', notNone = True) conutry_code = StringCol(length = 2, varchar = False, default = '', notNone = True) # until now I had to do this # mm_server_aliases = SQLMultipleJoin("mm_server_alias", joinColumn = "mm_serverID", orderBy = "server") # now it's perfect! mm_server_aliases = SQLMultipleJoin("mm_server_alias", orderBy = "server") class mm_server_alias(SQLObject): class sqlmeta: table = "smsarena.mm_server_alias" style = LongStyle(longID = True) _connection = conn_smsarena # until now I had to do this # mm_server = ForeignKey("mm_server", dbName = "id_mm_server") mm_server = ForeignKey("mm_server") server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") I hope it's clear :) Pau ---------------------------------------------------------------------- >Comment By: Pau Aliagas (linux4u) Date: 2006-02-17 10:13 Message: Logged In: YES user_id=140558 I've run the test with the latest SQLObject (no extra patches) and the tests fail too, at least they fail when I run them. As I explained before, there's something wrong when adding columns to sqlite, it fails and all the tests that depend on the added columns fail too. Does it happen to you too? ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-16 16:16 Message: Logged In: YES user_id=4799 These tests fail in both Postgres and SQLite. Two major backends (of 3) for SQLObject. If the problem is in tests you can patch tests, too... test_auto.py: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] > l = [p.phone for p in Person.selectBy(name='tim')[0].phones] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/test_auto.py:59] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > [failure to get at sourcelines from <TracebackEntry /home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1>] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def performJoin(self, inst): ids = inst._connection._SO_selectJoin( self.otherClass, self.joinColumn, > inst.id) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/joins.py:144] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _SO_selectJoin(self, soClass, column, value): return self.queryAll("SELECT %s FROM %s WHERE %s = %s" % (soClass.sqlmeta.idName, soClass.sqlmeta.table, column, > self.sqlrepr(value))) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:652] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def queryAll(self, s): > return self._runWithConnection(self._queryAll, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:327] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _runWithConnection(self, meth, *args): conn = self.getConnection() try: > val = meth(conn, *args) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:228] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _queryAll(self, conn, s): if self.debug: self.printDebug(conn, s, 'QueryAll') c = conn.cursor() > self._executeRetry(conn, c, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:320] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _executeRetry(self, conn, cursor, query): if self.debug: self.printDebug(conn, query, 'QueryR') E return cursor.execute(query) > OperationalError: no such column: person_id [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:306] - - - - - - - - - - - test_dynamicJoin: recorded stdout - - - - - - - - - - - 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/Query : DELETE FROM person 1/QueryR : DELETE FROM person 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/Query : DELETE FROM phone 1/QueryR : DELETE FROM phone 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jane') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 1 1/QueryR : SELECT name_col FROM person WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('tim') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 2 1/QueryR : SELECT name_col FROM person WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('bob') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 3 1/QueryR : SELECT name_col FROM person WHERE id = 3 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jake') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 4 1/QueryR : SELECT name_col FROM person WHERE id = 4 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-555-5555') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 1 1/QueryR : SELECT phone FROM phone WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-394-2930') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 2 1/QueryR : SELECT phone FROM phone WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('444-382-4854') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 3 1/QueryR : SELECT phone FROM phone WHERE id = 3 1/COMMIT : auto 1/Query : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/QueryR : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/COMMIT : auto 1/Select : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/QueryR : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/QueryAll: SELECT id FROM phone WHERE person_id = 2 1/QueryR : SELECT id FROM phone WHERE person_id = 2 1/COMMIT : auto ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 16:54 Message: Logged In: YES user_id=140558 Ok, here I go again. I've fixed a small bug: the name of the field was not porperly set when using Key(foreignKey... instead of ForeignKey. This fixes test_basic. And I think that there is nothing else to fix, I'm probably wrong, but I'll explain it hera. test_auto_old.py... FAIL test_auto.py... FAIL test_foreignKey.py... FAIL These tests fail because sqlite is failing when adding columns. In mysql it does not fail. I do not think it's this patch fault. And finally: test_SQLMultipleJoin.py... FAIL E assert str(hibrid.fightersAsSResult.sum('power')) == '23' > assert '23.0' == '23' + where '23.0' = str(23.0) + where 23.0 = <Race 3 name="'hibrid (human wi...'">.fightersAsSResult.sum('power') Again this is an error in the test. Please let me know if it can go in now :) If you can have a quick look at it better, it takes time to restart ths tests, I'd rather do it before I move on to another thing. Thanks Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-14 10:05 Message: Logged In: YES user_id=140558 Oleg, I've posted to the list because I run the tests and pass. I'm sure I'm doing something wrong but I don't see what. I lost more than 3 hours yesterday just trying to run te tests :( I printed things in dbtest.py and say that TESTDB did not change anything. I chenged manually conftest.py because I ahd a message that yoiu need sqlite2 for memory databases, but still I'm not sure everything works becasue I pass al the tests. Can you help me, I want to close this patch soon and move to other improvements but this is being much more difficult than it should. Thanks a lot Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-09 17:42 Message: Logged In: YES user_id=140558 I'm very busy but again will try to find some time to fix it. I'm using it every day without a glitch, even using the clause attributes like in the Complex example (new type of joins *toMany). I'll update it to latest SVN just in case this is the problem, I did it with that day's current. Please do not close it, I really intend to pass the tests, I'm already using it. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-09 17:11 Message: Logged In: YES user_id=4799 test_auto.py, for example fails: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] l = [p.phone for p in Person.selectBy(name='tim')[0].phones] l.sort() E assert l == ['555-394-2930', '555-555-5555'] > assert [] == ['555-394-2930', '555-555-5555'] [sqlobject/tests/test_auto.py:61] ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 19:10 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 19:07 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-30 18:57 Message: Logged In: YES user_id=4799 test_auto.py, test_auto_old.py and test_basic.py failed. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 17:04 Message: Logged In: YES user_id=140558 This is the final patch against latest svn, it includes everything in one single patch. It passes the tests. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 14:17 Message: Logged In: YES user_id=140558 Ok, I have taken my time to understand pydist, test, etc, and here I am back with the working solution :) Now the resulting SQLobject passes all the tests. I attach an incremental patch so that you can see more clearly the changes done to fix the previous one. I've needed a new method in the Style class, instanceIDAttrToAttr, that is the complementary to the already known instanceAttrToIDAttr. If you need to transform back and forth field names, you need them both. I haven't tried to port it to the latest svn yet, this is against the same release than the first patch, but it should apply more or less clearly as this are very isolated areas in the code. When I do it I'll post it here. Sorry for the delay, it has not been easy for me to understand more deeply the code and, even less, to know how the tests work :) ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-03 13:18 Message: Logged In: YES user_id=140558 It fails because the test is not right, it still has the ID postfix hardcoded. My fault, I did no send a patch for tests. This is the piece that fails: # Select by usual way s = TestWorkKey.selectBy(composerID=c.id, title='Symphony No. 9') I have not looked at tests until now, but it looks like there should be tests for the different provides styles, in this case, if you accept the patch, at least a test for the LongStyle provided and for the current naming styles. I'll try to cook up something, but it can take a little time. Any guidelines will be appreciated (I've just read the docs ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-03 12:23 Message: Logged In: YES user_id=4799 test_selectBy_foreignKey.py fails: def test1(): setupClass([TestComposerKey, TestWorkKey]) c = TestComposerKey(name='Mahler, Gustav') > w1 = TestWorkKey(composer=c, title='Symphony No. 9') [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/tests/test_selectBy_foreignKey.py:19] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def __init__(self, **kw): # The get() classmethod/constructor uses a magic keyword # argument when it wants an empty object, fetched from the # database. So we have nothing more to do in that case: if kw.has_key('_SO_fetch_no_create'): return post_funcs = [] self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) # Pass the connection object along if we were given one. if kw.has_key('connection'): self._connection = kw['connection'] self.sqlmeta._perConnection = True del kw['connection'] self._SO_writeLock = threading.Lock() if kw.has_key('id'): id = self.sqlmeta.idType(kw['id']) del kw['id'] else: id = None > self._create(id, **kw) [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1210] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _create(self, id, **kw): self.sqlmeta._creating = True self._SO_createValues = {} self._SO_validatorState = SQLObjectState(self) # First we do a little fix-up on the keywords we were # passed: for column in self.sqlmeta.columnList: # Then we check if the column wasn't passed in, and # if not we try to get the default. if not kw.has_key(column.name) and not kw.has_key(column.foreignName): default = column.default # If we don't get it, it's an error: if default is NoDefault: E raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, column.name) > TypeError: TestWorkKey() did not get expected keyword argument composerID [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1231] - - - - - - - - - - - - - test1: recorded stdout - - - - - - - - - - - - - - 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/QueryR : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/QueryR : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/COMMIT : auto 1/Query : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/QueryR : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/COMMIT : auto 1/QueryIns: INSERT INTO test_composer_key (id, name) VALUES (1, 'Mahler, Gustav') 1/COMMIT : auto 1/QueryOne: SELECT name FROM test_composer_key WHERE id = 1 1/QueryR : SELECT name FROM test_composer_key WHERE id = 1 1/COMMIT : auto ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 |
|
From: <sub...@co...> - 2006-02-16 17:14:49
|
Author: randall
Date: 2006-02-16 10:14:42 -0700 (Thu, 16 Feb 2006)
New Revision: 1604
Modified:
SQLObject/branches/0.7-bugfix/sqlobject/postgres/pgconnection.py
Log:
Added support for schema when checking if table exits.
Modified: SQLObject/branches/0.7-bugfix/sqlobject/postgres/pgconnection.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/postgres/pgconnection.py 2006-02-16 16:53:41 UTC (rev 1603)
+++ SQLObject/branches/0.7-bugfix/sqlobject/postgres/pgconnection.py 2006-02-16 17:14:42 UTC (rev 1604)
@@ -157,8 +157,19 @@
return 'INT NOT NULL'
def tableExists(self, tableName):
- result = self.queryOne("SELECT COUNT(relname) FROM pg_class WHERE relname = %s"
- % self.sqlrepr(tableName))
+ if '.' in tableName and self.server_version[:3] >= "7.4":
+ (table_schema, table_name) = tableName.split('.')
+ query = """
+ SELECT COUNT(*) FROM information_schema.tables
+ WHERE table_schema = %s
+ AND table_name = %s
+ """ % (self.sqlrepr(table_schema), self.sqlrepr(table_name))
+ else:
+ query = """
+ SELECT COUNT(relname) FROM pg_class
+ WHERE relname = %s
+ """ % self.sqlrepr(tableName)
+ result = self.queryOne(query)
return result[0]
def addColumn(self, tableName, column):
|
|
From: <sub...@co...> - 2006-02-16 16:53:50
|
Author: phd
Date: 2006-02-16 09:53:41 -0700 (Thu, 16 Feb 2006)
New Revision: 1603
Modified:
home/phd/SQLObject/paramstyles/sqlobject/__init__.py
home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_select.py
Log:
Merged patches from the revisions 1600:1602 from the trunk: applied the patch 1410834: add RLIKE operator; added tests for LIKE and RLIKE.
Modified: home/phd/SQLObject/paramstyles/sqlobject/__init__.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/__init__.py 2006-02-16 16:51:22 UTC (rev 1602)
+++ home/phd/SQLObject/paramstyles/sqlobject/__init__.py 2006-02-16 16:53:41 UTC (rev 1603)
@@ -1,6 +1,6 @@
from main import *
from col import *
-from sqlbuilder import AND, OR, NOT, IN, LIKE, DESC, CONTAINSSTRING, const, func
+from sqlbuilder import AND, OR, NOT, IN, LIKE, RLIKE, DESC, CONTAINSSTRING, const, func
from styles import *
from joins import *
from index import *
Modified: home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2006-02-16 16:51:22 UTC (rev 1602)
+++ home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2006-02-16 16:53:41 UTC (rev 1603)
@@ -271,17 +271,6 @@
elif self.op == "OR":
return execute(self.expr1, executor) \
or execute(self.expr2, executor)
- elif self.op == "LIKE":
- if not hasattr(self, '_regex'):
- # @@: Crude, not entirely accurate
- dest = self.expr2
- dest = dest.replace("%%", "\001")
- dest = dest.replace("*", "\002")
- dest = dest.replace("%", "*")
- dest = dest.replace("\001", "%")
- dest = dest.replace("\002", "[*]")
- self._regex = re.compile(fnmatch.translate(dest), re.I)
- return self._regex.search(execute(self.expr1, executor))
else:
return operatorMap[self.op.upper()](execute(self.expr1, executor),
execute(self.expr2, executor))
@@ -745,9 +734,6 @@
else:
return NOT(_IN(item, list))
-def LIKE(expr, string):
- return SQLOp("LIKE", expr, string)
-
def STARTSWITH(expr, string):
return SQLOp("LIKE", expr, _LikeQuoted(string) + '%')
@@ -1013,6 +999,49 @@
self.q = OuterTable(table)
+class LIKE(SQLExpression):
+ op = "LIKE"
+
+ def __init__(self, expr, string):
+ self.expr = expr
+ self.string = string
+ def __sqlrepr__(self, db):
+ return "(%s %s %s)" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
+ def components(self):
+ return [self.expr, self.string]
+ def execute(self, executor):
+ if not hasattr(self, '_regex'):
+ # @@: Crude, not entirely accurate
+ dest = self.string
+ dest = dest.replace("%%", "\001")
+ dest = dest.replace("*", "\002")
+ dest = dest.replace("%", "*")
+ dest = dest.replace("\001", "%")
+ dest = dest.replace("\002", "[*]")
+ self._regex = re.compile(fnmatch.translate(dest), re.I)
+ return self._regex.search(execute(self.expr, executor))
+
+class RLIKE(LIKE):
+ op = "RLIKE"
+
+ def _get_op(self, db):
+ if db in ('mysql', 'maxdb', 'firebird'):
+ return "RLIKE"
+ elif db == 'sqlite':
+ return "REGEXP"
+ elif db == 'postgres':
+ return "~"
+ else:
+ return "LIKE"
+ def __sqlrepr__(self, db):
+ return "(%s %s %s)" % (
+ sqlrepr(self.expr, db), self._get_op(db), sqlrepr(self.string, db)
+ )
+ def execute(self, executor):
+ self.op = self._get_op(self.db)
+ return LIKE.execute(self, executor)
+
+
class INSubquery(SQLExpression):
op = "IN"
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_select.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_select.py 2006-02-16 16:51:22 UTC (rev 1602)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_select.py 2006-02-16 16:53:41 UTC (rev 1603)
@@ -132,3 +132,39 @@
def test_2(self):
self.accumulateEqual(len,Counter2.select('all'), 100)
+
+def test_sqlbuilder_LIKE():
+ setupClass(IterTest)
+ IterTest(name='sqlobject')
+ IterTest(name='sqlbuilder')
+ assert IterTest.select(LIKE(IterTest.q.name, "sql%")).count() == 2
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlb%")).count() == 1
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlb%")).count() == 1
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlx%")).count() == 0
+
+def test_sqlbuilder_RLIKE():
+ setupClass(IterTest)
+
+ if IterTest._connection.dbName == "sqlite":
+ from sqlobject.sqlite.sqliteconnection import using_sqlite2
+ if not using_sqlite2:
+ return
+
+ # Implement regexp() function for SQLite; only works with PySQLite2
+ import re
+ def regexp(regexp, test):
+ return bool(re.search(regexp, test))
+
+ _get_connection = IterTest._connection.getConnection
+ def new_get_connection(*args, **kw):
+ _connection = _get_connection(*args, **kw)
+ _connection.create_function("regexp", 2, regexp)
+ return _connection
+ IterTest._connection.getConnection = new_get_connection
+
+ IterTest(name='sqlobject')
+ IterTest(name='sqlbuilder')
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sql.*$")).count() == 2
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlb.*$")).count() == 1
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlb.*$")).count() == 1
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlx.*$")).count() == 0
|
|
From: SourceForge.net <no...@so...> - 2006-02-16 16:53:12
|
Patches item #1410834, was opened at 2006-01-20 17:21 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed Resolution: Accepted Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: add RLIKE operator Initial Comment: Well, it looks like I'm inspired. I tried to do all the regular expression matching in python, but it was too slow, as I need to select records based on an expresion matching. So I have implemented RLIKE, also known as REGEXP or Posix Regular Expressions. You can use it as any other operator! mysql and firebird call it REGEXP and RLIKE postgres calls it ~ The rest just do not support it, so I've made it behave like "LIKE", as I did not find a standard manner not to support it. It's not a bad solution :) The patch is really trivial, I've tested it with many records (in mysql) and works as expected. I've tested the resulting SQL in postgres and it works too. Hope you can include it. ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-02-16 19:53 Message: Logged In: YES user_id=4799 Applied and committed to the trunk in the revision 1601, 1602 for 0.7-branch. I made some changes and added tests for LIKE and RLIKE. Please look and run tests - does it work for you with MySQL and SQLite? ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-16 18:30 Message: Logged In: YES user_id=4799 This one is much better! You've missed an important point - __sqlrepr__() in RLIKE. I added it. I also added tests for both LIKE and RLIKE. The test for RLIKE fails for SQLIte because SQLIte treats REGEXP specially - a user must define his/her own regexp() funcion. I am going to experiment with PySQLite2 functions and then commit. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 20:00 Message: Logged In: YES user_id=140558 Let's see if you like this one. I've mcreated an own class for LIKE, moved it away from SQLOp and derived RLIKE from it. I pass all the tests and LIKE and RLIKE work a expected (tested in mysql), LIKE shoule still work in the rest of databases as the change is purely internal. For RLIKE I looked at the manuals, it should work AFAICT. We could even add REGEXP as another class effortlessly, but I'm not sure you want to have several way to do the same thing. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-13 22:26 Message: Logged In: YES user_id=4799 Take a look at INSubquery, NOTINSubquery, Subquery and EXISTS. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-13 21:37 Message: Logged In: YES user_id=140558 I tried to mimic LIKE as much as possible, that's why I did it this way. Moreover I could not find any example of doing it as you suggest. I had a look at the documentation and the generated SQL should be valid in all cases (REGEXP is also called RLIKE in mysql, I picked RLIKE to make it more natural, I also used REGEXP). If you could point me in the right direction, I could probably redo the patch as I'm aleady using it instead of direct use of SQL. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-13 19:39 Message: Logged In: YES user_id=4799 The patch is invalid. SQLObject renders SQLOp("RLIKE", expr) as "RLIKE " + expr. In SQLObject the operator is really called REGEXP, in Postgres ~. The patch tries to replace "RLIKE" to DBMS-specific name by replacing self.op (this is fragile by itself) but in a wrong time - in .execute(). Instead of SQLOp("RLIKE", expr) the thing should be implemented as a separate expression class, something like this: class RLIKE(SQLOp): def __sqlrepr__(self, db): ... ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-31 18:24 Message: Logged In: YES user_id=4799 There is much overlap between LIKE and RLIKE. Can you refactor it to remove duplicate code? ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-20 18:03 Message: Logged In: YES user_id=140558 Sorry, I attached the worng patch, this is the good one. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 |
|
From: <sub...@co...> - 2006-02-16 16:51:27
|
Author: phd
Date: 2006-02-16 09:51:22 -0700 (Thu, 16 Feb 2006)
New Revision: 1602
Modified:
SQLObject/branches/0.7-bugfix/sqlobject/__init__.py
SQLObject/branches/0.7-bugfix/sqlobject/sqlbuilder.py
SQLObject/branches/0.7-bugfix/sqlobject/tests/test_select.py
Log:
Applied the patch 1410834: add RLIKE operator; added tests for LIKE and RLIKE.
Modified: SQLObject/branches/0.7-bugfix/sqlobject/__init__.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/__init__.py 2006-02-16 16:50:16 UTC (rev 1601)
+++ SQLObject/branches/0.7-bugfix/sqlobject/__init__.py 2006-02-16 16:51:22 UTC (rev 1602)
@@ -1,6 +1,6 @@
from main import *
from col import *
-from sqlbuilder import AND, OR, NOT, IN, LIKE, DESC, CONTAINSSTRING, const, func
+from sqlbuilder import AND, OR, NOT, IN, LIKE, RLIKE, DESC, CONTAINSSTRING, const, func
from styles import *
from joins import *
from index import *
Modified: SQLObject/branches/0.7-bugfix/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/sqlbuilder.py 2006-02-16 16:50:16 UTC (rev 1601)
+++ SQLObject/branches/0.7-bugfix/sqlobject/sqlbuilder.py 2006-02-16 16:51:22 UTC (rev 1602)
@@ -237,17 +237,6 @@
elif self.op == "OR":
return execute(self.expr1, executor) \
or execute(self.expr2, executor)
- elif self.op == "LIKE":
- if not hasattr(self, '_regex'):
- # @@: Crude, not entirely accurate
- dest = self.expr2
- dest = dest.replace("%%", "\001")
- dest = dest.replace("*", "\002")
- dest = dest.replace("%", "*")
- dest = dest.replace("\001", "%")
- dest = dest.replace("\002", "[*]")
- self._regex = re.compile(fnmatch.translate(dest), re.I)
- return self._regex.search(execute(self.expr1, executor))
else:
return operatorMap[self.op.upper()](execute(self.expr1, executor),
execute(self.expr2, executor))
@@ -622,9 +611,6 @@
else:
return NOT(_IN(item, list))
-def LIKE(expr, string):
- return SQLOp("LIKE", expr, string)
-
def STARTSWITH(expr, string):
return SQLOp("LIKE", expr, _LikeQuoted(string) + '%')
@@ -890,6 +876,49 @@
self.q = OuterTable(table)
+class LIKE(SQLExpression):
+ op = "LIKE"
+
+ def __init__(self, expr, string):
+ self.expr = expr
+ self.string = string
+ def __sqlrepr__(self, db):
+ return "(%s %s %s)" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
+ def components(self):
+ return [self.expr, self.string]
+ def execute(self, executor):
+ if not hasattr(self, '_regex'):
+ # @@: Crude, not entirely accurate
+ dest = self.string
+ dest = dest.replace("%%", "\001")
+ dest = dest.replace("*", "\002")
+ dest = dest.replace("%", "*")
+ dest = dest.replace("\001", "%")
+ dest = dest.replace("\002", "[*]")
+ self._regex = re.compile(fnmatch.translate(dest), re.I)
+ return self._regex.search(execute(self.expr, executor))
+
+class RLIKE(LIKE):
+ op = "RLIKE"
+
+ def _get_op(self, db):
+ if db in ('mysql', 'maxdb', 'firebird'):
+ return "RLIKE"
+ elif db == 'sqlite':
+ return "REGEXP"
+ elif db == 'postgres':
+ return "~"
+ else:
+ return "LIKE"
+ def __sqlrepr__(self, db):
+ return "(%s %s %s)" % (
+ sqlrepr(self.expr, db), self._get_op(db), sqlrepr(self.string, db)
+ )
+ def execute(self, executor):
+ self.op = self._get_op(self.db)
+ return LIKE.execute(self, executor)
+
+
class INSubquery(SQLExpression):
op = "IN"
Modified: SQLObject/branches/0.7-bugfix/sqlobject/tests/test_select.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/tests/test_select.py 2006-02-16 16:50:16 UTC (rev 1601)
+++ SQLObject/branches/0.7-bugfix/sqlobject/tests/test_select.py 2006-02-16 16:51:22 UTC (rev 1602)
@@ -118,3 +118,39 @@
def test_2(self):
self.accumulateEqual(len,Counter2.select('all'), 100)
+
+def test_sqlbuilder_LIKE():
+ setupClass(IterTest)
+ IterTest(name='sqlobject')
+ IterTest(name='sqlbuilder')
+ assert IterTest.select(LIKE(IterTest.q.name, "sql%")).count() == 2
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlb%")).count() == 1
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlb%")).count() == 1
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlx%")).count() == 0
+
+def test_sqlbuilder_RLIKE():
+ setupClass(IterTest)
+
+ if IterTest._connection.dbName == "sqlite":
+ from sqlobject.sqlite.sqliteconnection import using_sqlite2
+ if not using_sqlite2:
+ return
+
+ # Implement regexp() function for SQLite; only works with PySQLite2
+ import re
+ def regexp(regexp, test):
+ return bool(re.search(regexp, test))
+
+ _get_connection = IterTest._connection.getConnection
+ def new_get_connection(*args, **kw):
+ _connection = _get_connection(*args, **kw)
+ _connection.create_function("regexp", 2, regexp)
+ return _connection
+ IterTest._connection.getConnection = new_get_connection
+
+ IterTest(name='sqlobject')
+ IterTest(name='sqlbuilder')
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sql.*$")).count() == 2
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlb.*$")).count() == 1
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlb.*$")).count() == 1
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlx.*$")).count() == 0
|
|
From: <sub...@co...> - 2006-02-16 16:50:30
|
Author: phd
Date: 2006-02-16 09:50:16 -0700 (Thu, 16 Feb 2006)
New Revision: 1601
Modified:
SQLObject/trunk/sqlobject/__init__.py
SQLObject/trunk/sqlobject/sqlbuilder.py
SQLObject/trunk/sqlobject/tests/test_select.py
Log:
Applied the patch 1410834: add RLIKE operator; added tests for LIKE and RLIKE.
Modified: SQLObject/trunk/sqlobject/__init__.py
===================================================================
--- SQLObject/trunk/sqlobject/__init__.py 2006-02-15 18:58:39 UTC (rev 1600)
+++ SQLObject/trunk/sqlobject/__init__.py 2006-02-16 16:50:16 UTC (rev 1601)
@@ -1,6 +1,6 @@
from main import *
from col import *
-from sqlbuilder import AND, OR, NOT, IN, LIKE, DESC, CONTAINSSTRING, const, func
+from sqlbuilder import AND, OR, NOT, IN, LIKE, RLIKE, DESC, CONTAINSSTRING, const, func
from styles import *
from joins import *
from index import *
Modified: SQLObject/trunk/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/trunk/sqlobject/sqlbuilder.py 2006-02-15 18:58:39 UTC (rev 1600)
+++ SQLObject/trunk/sqlobject/sqlbuilder.py 2006-02-16 16:50:16 UTC (rev 1601)
@@ -240,17 +240,6 @@
elif self.op == "OR":
return execute(self.expr1, executor) \
or execute(self.expr2, executor)
- elif self.op == "LIKE":
- if not hasattr(self, '_regex'):
- # @@: Crude, not entirely accurate
- dest = self.expr2
- dest = dest.replace("%%", "\001")
- dest = dest.replace("*", "\002")
- dest = dest.replace("%", "*")
- dest = dest.replace("\001", "%")
- dest = dest.replace("\002", "[*]")
- self._regex = re.compile(fnmatch.translate(dest), re.I)
- return self._regex.search(execute(self.expr1, executor))
else:
return operatorMap[self.op.upper()](execute(self.expr1, executor),
execute(self.expr2, executor))
@@ -625,9 +614,6 @@
else:
return NOT(_IN(item, list))
-def LIKE(expr, string):
- return SQLOp("LIKE", expr, string)
-
def STARTSWITH(expr, string):
return SQLOp("LIKE", expr, _LikeQuoted(string) + '%')
@@ -893,6 +879,49 @@
self.q = OuterTable(table)
+class LIKE(SQLExpression):
+ op = "LIKE"
+
+ def __init__(self, expr, string):
+ self.expr = expr
+ self.string = string
+ def __sqlrepr__(self, db):
+ return "(%s %s %s)" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
+ def components(self):
+ return [self.expr, self.string]
+ def execute(self, executor):
+ if not hasattr(self, '_regex'):
+ # @@: Crude, not entirely accurate
+ dest = self.string
+ dest = dest.replace("%%", "\001")
+ dest = dest.replace("*", "\002")
+ dest = dest.replace("%", "*")
+ dest = dest.replace("\001", "%")
+ dest = dest.replace("\002", "[*]")
+ self._regex = re.compile(fnmatch.translate(dest), re.I)
+ return self._regex.search(execute(self.expr, executor))
+
+class RLIKE(LIKE):
+ op = "RLIKE"
+
+ def _get_op(self, db):
+ if db in ('mysql', 'maxdb', 'firebird'):
+ return "RLIKE"
+ elif db == 'sqlite':
+ return "REGEXP"
+ elif db == 'postgres':
+ return "~"
+ else:
+ return "LIKE"
+ def __sqlrepr__(self, db):
+ return "(%s %s %s)" % (
+ sqlrepr(self.expr, db), self._get_op(db), sqlrepr(self.string, db)
+ )
+ def execute(self, executor):
+ self.op = self._get_op(self.db)
+ return LIKE.execute(self, executor)
+
+
class INSubquery(SQLExpression):
op = "IN"
Modified: SQLObject/trunk/sqlobject/tests/test_select.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_select.py 2006-02-15 18:58:39 UTC (rev 1600)
+++ SQLObject/trunk/sqlobject/tests/test_select.py 2006-02-16 16:50:16 UTC (rev 1601)
@@ -132,3 +132,39 @@
def test_2(self):
self.accumulateEqual(len,Counter2.select('all'), 100)
+
+def test_sqlbuilder_LIKE():
+ setupClass(IterTest)
+ IterTest(name='sqlobject')
+ IterTest(name='sqlbuilder')
+ assert IterTest.select(LIKE(IterTest.q.name, "sql%")).count() == 2
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlb%")).count() == 1
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlb%")).count() == 1
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlx%")).count() == 0
+
+def test_sqlbuilder_RLIKE():
+ setupClass(IterTest)
+
+ if IterTest._connection.dbName == "sqlite":
+ from sqlobject.sqlite.sqliteconnection import using_sqlite2
+ if not using_sqlite2:
+ return
+
+ # Implement regexp() function for SQLite; only works with PySQLite2
+ import re
+ def regexp(regexp, test):
+ return bool(re.search(regexp, test))
+
+ _get_connection = IterTest._connection.getConnection
+ def new_get_connection(*args, **kw):
+ _connection = _get_connection(*args, **kw)
+ _connection.create_function("regexp", 2, regexp)
+ return _connection
+ IterTest._connection.getConnection = new_get_connection
+
+ IterTest(name='sqlobject')
+ IterTest(name='sqlbuilder')
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sql.*$")).count() == 2
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlb.*$")).count() == 1
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlb.*$")).count() == 1
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlx.*$")).count() == 0
|
|
From: SourceForge.net <no...@so...> - 2006-02-16 15:30:18
|
Patches item #1410834, was opened at 2006-01-20 17:21 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open >Resolution: Accepted Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: add RLIKE operator Initial Comment: Well, it looks like I'm inspired. I tried to do all the regular expression matching in python, but it was too slow, as I need to select records based on an expresion matching. So I have implemented RLIKE, also known as REGEXP or Posix Regular Expressions. You can use it as any other operator! mysql and firebird call it REGEXP and RLIKE postgres calls it ~ The rest just do not support it, so I've made it behave like "LIKE", as I did not find a standard manner not to support it. It's not a bad solution :) The patch is really trivial, I've tested it with many records (in mysql) and works as expected. I've tested the resulting SQL in postgres and it works too. Hope you can include it. ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-02-16 18:30 Message: Logged In: YES user_id=4799 This one is much better! You've missed an important point - __sqlrepr__() in RLIKE. I added it. I also added tests for both LIKE and RLIKE. The test for RLIKE fails for SQLIte because SQLIte treats REGEXP specially - a user must define his/her own regexp() funcion. I am going to experiment with PySQLite2 functions and then commit. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 20:00 Message: Logged In: YES user_id=140558 Let's see if you like this one. I've mcreated an own class for LIKE, moved it away from SQLOp and derived RLIKE from it. I pass all the tests and LIKE and RLIKE work a expected (tested in mysql), LIKE shoule still work in the rest of databases as the change is purely internal. For RLIKE I looked at the manuals, it should work AFAICT. We could even add REGEXP as another class effortlessly, but I'm not sure you want to have several way to do the same thing. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-13 22:26 Message: Logged In: YES user_id=4799 Take a look at INSubquery, NOTINSubquery, Subquery and EXISTS. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-13 21:37 Message: Logged In: YES user_id=140558 I tried to mimic LIKE as much as possible, that's why I did it this way. Moreover I could not find any example of doing it as you suggest. I had a look at the documentation and the generated SQL should be valid in all cases (REGEXP is also called RLIKE in mysql, I picked RLIKE to make it more natural, I also used REGEXP). If you could point me in the right direction, I could probably redo the patch as I'm aleady using it instead of direct use of SQL. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-13 19:39 Message: Logged In: YES user_id=4799 The patch is invalid. SQLObject renders SQLOp("RLIKE", expr) as "RLIKE " + expr. In SQLObject the operator is really called REGEXP, in Postgres ~. The patch tries to replace "RLIKE" to DBMS-specific name by replacing self.op (this is fragile by itself) but in a wrong time - in .execute(). Instead of SQLOp("RLIKE", expr) the thing should be implemented as a separate expression class, something like this: class RLIKE(SQLOp): def __sqlrepr__(self, db): ... ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-31 18:24 Message: Logged In: YES user_id=4799 There is much overlap between LIKE and RLIKE. Can you refactor it to remove duplicate code? ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-20 18:03 Message: Logged In: YES user_id=140558 Sorry, I attached the worng patch, this is the good one. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-16 15:16:16
|
Patches item #1353728, was opened at 2005-11-11 10:20 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: define foreign keys in Style Initial Comment: I don't like to use attrID all along the code to access related tables, I want to be able use the nomeclature I like taking advantage of the nice Style idea. This is especially true when you create RelatedJoins when you use a nomeclature like I do (table.id_table), but it's the same for all the nomeclatures you can imagine. In styles.py it warns: def instanceAttrToIDAttr(self, attr): # @@: Right now, because of how names are created for foreign # keys, you can't really change this style. return attr + "ID" With this patch you can define how you want the foreign keys generated, they won't be mandatorily generated as attrID. Example: class LongStyle(Style): """ This style is derived from Style, that does not do any translation, but constructs the table ids like id_table. """ def instanceAttrToIDAttr(self, attr): return "id_" + attr def tableReference(self, table): # str.rsplit is python 2.4+ only if version_info >= (2, 4): return "id_" + table.rsplit(".", 1)[-1] else: return "id_" + rsplit(table, ".", 1)[-1] class mm_server(SQLObject): class sqlmeta: table = "smsarena.mm_server" style = LongStyle(longID = True) _connection = conn_smsarena server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") tz = StringCol(length = 20, default = 'CET', notNone = True) conutry_code = StringCol(length = 2, varchar = False, default = '', notNone = True) # until now I had to do this # mm_server_aliases = SQLMultipleJoin("mm_server_alias", joinColumn = "mm_serverID", orderBy = "server") # now it's perfect! mm_server_aliases = SQLMultipleJoin("mm_server_alias", orderBy = "server") class mm_server_alias(SQLObject): class sqlmeta: table = "smsarena.mm_server_alias" style = LongStyle(longID = True) _connection = conn_smsarena # until now I had to do this # mm_server = ForeignKey("mm_server", dbName = "id_mm_server") mm_server = ForeignKey("mm_server") server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") I hope it's clear :) Pau ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-02-16 18:16 Message: Logged In: YES user_id=4799 These tests fail in both Postgres and SQLite. Two major backends (of 3) for SQLObject. If the problem is in tests you can patch tests, too... test_auto.py: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] > l = [p.phone for p in Person.selectBy(name='tim')[0].phones] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/test_auto.py:59] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > [failure to get at sourcelines from <TracebackEntry /home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1>] [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/tests/<string>:1] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def performJoin(self, inst): ids = inst._connection._SO_selectJoin( self.otherClass, self.joinColumn, > inst.id) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/joins.py:144] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _SO_selectJoin(self, soClass, column, value): return self.queryAll("SELECT %s FROM %s WHERE %s = %s" % (soClass.sqlmeta.idName, soClass.sqlmeta.table, column, > self.sqlrepr(value))) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:652] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def queryAll(self, s): > return self._runWithConnection(self._queryAll, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:327] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _runWithConnection(self, meth, *args): conn = self.getConnection() try: > val = meth(conn, *args) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:228] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _queryAll(self, conn, s): if self.debug: self.printDebug(conn, s, 'QueryAll') c = conn.cursor() > self._executeRetry(conn, c, s) [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:320] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _executeRetry(self, conn, cursor, query): if self.debug: self.printDebug(conn, query, 'QueryR') E return cursor.execute(query) > OperationalError: no such column: person_id [/home/phd/work/SQLObject/SQLObject-rlike/sqlobject/dbconnection.py:306] - - - - - - - - - - - test_dynamicJoin: recorded stdout - - - - - - - - - - - 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/Query : DELETE FROM person 1/QueryR : DELETE FROM person 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'person' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/Query : DELETE FROM phone 1/QueryR : DELETE FROM phone 1/COMMIT : auto 1/QueryOne: SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/QueryR : SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name = 'phone' 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jane') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 1 1/QueryR : SELECT name_col FROM person WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('tim') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 2 1/QueryR : SELECT name_col FROM person WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('bob') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 3 1/QueryR : SELECT name_col FROM person WHERE id = 3 1/COMMIT : auto 1/QueryIns: INSERT INTO person (name_col) VALUES ('jake') 1/COMMIT : auto 1/QueryOne: SELECT name_col FROM person WHERE id = 4 1/QueryR : SELECT name_col FROM person WHERE id = 4 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-555-5555') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 1 1/QueryR : SELECT phone FROM phone WHERE id = 1 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('555-394-2930') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 2 1/QueryR : SELECT phone FROM phone WHERE id = 2 1/COMMIT : auto 1/QueryIns: INSERT INTO phone (phone) VALUES ('444-382-4854') 1/COMMIT : auto 1/QueryOne: SELECT phone FROM phone WHERE id = 3 1/QueryR : SELECT phone FROM phone WHERE id = 3 1/COMMIT : auto 1/Query : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/QueryR : ALTER TABLE phone ADD COLUMN person_i_d_id INT 1/COMMIT : auto 1/Select : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/QueryR : SELECT phone.id, phone.phone, phone.person_i_d_id FROM phone WHERE 1 = 1 ORDER BY phone 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'bob' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/Select : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/QueryR : SELECT person.id, person.name_col FROM person WHERE name_col = 'tim' ORDER BY name_col LIMIT 1 1/COMMIT : auto 1/QueryAll: SELECT id FROM phone WHERE person_id = 2 1/QueryR : SELECT id FROM phone WHERE person_id = 2 1/COMMIT : auto ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 18:54 Message: Logged In: YES user_id=140558 Ok, here I go again. I've fixed a small bug: the name of the field was not porperly set when using Key(foreignKey... instead of ForeignKey. This fixes test_basic. And I think that there is nothing else to fix, I'm probably wrong, but I'll explain it hera. test_auto_old.py... FAIL test_auto.py... FAIL test_foreignKey.py... FAIL These tests fail because sqlite is failing when adding columns. In mysql it does not fail. I do not think it's this patch fault. And finally: test_SQLMultipleJoin.py... FAIL E assert str(hibrid.fightersAsSResult.sum('power')) == '23' > assert '23.0' == '23' + where '23.0' = str(23.0) + where 23.0 = <Race 3 name="'hibrid (human wi...'">.fightersAsSResult.sum('power') Again this is an error in the test. Please let me know if it can go in now :) If you can have a quick look at it better, it takes time to restart ths tests, I'd rather do it before I move on to another thing. Thanks Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-14 12:05 Message: Logged In: YES user_id=140558 Oleg, I've posted to the list because I run the tests and pass. I'm sure I'm doing something wrong but I don't see what. I lost more than 3 hours yesterday just trying to run te tests :( I printed things in dbtest.py and say that TESTDB did not change anything. I chenged manually conftest.py because I ahd a message that yoiu need sqlite2 for memory databases, but still I'm not sure everything works becasue I pass al the tests. Can you help me, I want to close this patch soon and move to other improvements but this is being much more difficult than it should. Thanks a lot Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-09 19:42 Message: Logged In: YES user_id=140558 I'm very busy but again will try to find some time to fix it. I'm using it every day without a glitch, even using the clause attributes like in the Complex example (new type of joins *toMany). I'll update it to latest SVN just in case this is the problem, I did it with that day's current. Please do not close it, I really intend to pass the tests, I'm already using it. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-09 19:11 Message: Logged In: YES user_id=4799 test_auto.py, for example fails: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] l = [p.phone for p in Person.selectBy(name='tim')[0].phones] l.sort() E assert l == ['555-394-2930', '555-555-5555'] > assert [] == ['555-394-2930', '555-555-5555'] [sqlobject/tests/test_auto.py:61] ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 21:10 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 21:07 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-30 20:57 Message: Logged In: YES user_id=4799 test_auto.py, test_auto_old.py and test_basic.py failed. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 19:04 Message: Logged In: YES user_id=140558 This is the final patch against latest svn, it includes everything in one single patch. It passes the tests. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 16:17 Message: Logged In: YES user_id=140558 Ok, I have taken my time to understand pydist, test, etc, and here I am back with the working solution :) Now the resulting SQLobject passes all the tests. I attach an incremental patch so that you can see more clearly the changes done to fix the previous one. I've needed a new method in the Style class, instanceIDAttrToAttr, that is the complementary to the already known instanceAttrToIDAttr. If you need to transform back and forth field names, you need them both. I haven't tried to port it to the latest svn yet, this is against the same release than the first patch, but it should apply more or less clearly as this are very isolated areas in the code. When I do it I'll post it here. Sorry for the delay, it has not been easy for me to understand more deeply the code and, even less, to know how the tests work :) ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-03 15:18 Message: Logged In: YES user_id=140558 It fails because the test is not right, it still has the ID postfix hardcoded. My fault, I did no send a patch for tests. This is the piece that fails: # Select by usual way s = TestWorkKey.selectBy(composerID=c.id, title='Symphony No. 9') I have not looked at tests until now, but it looks like there should be tests for the different provides styles, in this case, if you accept the patch, at least a test for the LongStyle provided and for the current naming styles. I'll try to cook up something, but it can take a little time. Any guidelines will be appreciated (I've just read the docs ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-03 14:23 Message: Logged In: YES user_id=4799 test_selectBy_foreignKey.py fails: def test1(): setupClass([TestComposerKey, TestWorkKey]) c = TestComposerKey(name='Mahler, Gustav') > w1 = TestWorkKey(composer=c, title='Symphony No. 9') [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/tests/test_selectBy_foreignKey.py:19] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def __init__(self, **kw): # The get() classmethod/constructor uses a magic keyword # argument when it wants an empty object, fetched from the # database. So we have nothing more to do in that case: if kw.has_key('_SO_fetch_no_create'): return post_funcs = [] self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) # Pass the connection object along if we were given one. if kw.has_key('connection'): self._connection = kw['connection'] self.sqlmeta._perConnection = True del kw['connection'] self._SO_writeLock = threading.Lock() if kw.has_key('id'): id = self.sqlmeta.idType(kw['id']) del kw['id'] else: id = None > self._create(id, **kw) [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1210] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _create(self, id, **kw): self.sqlmeta._creating = True self._SO_createValues = {} self._SO_validatorState = SQLObjectState(self) # First we do a little fix-up on the keywords we were # passed: for column in self.sqlmeta.columnList: # Then we check if the column wasn't passed in, and # if not we try to get the default. if not kw.has_key(column.name) and not kw.has_key(column.foreignName): default = column.default # If we don't get it, it's an error: if default is NoDefault: E raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, column.name) > TypeError: TestWorkKey() did not get expected keyword argument composerID [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1231] - - - - - - - - - - - - - test1: recorded stdout - - - - - - - - - - - - - - 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/QueryR : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/QueryR : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/COMMIT : auto 1/Query : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/QueryR : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/COMMIT : auto 1/QueryIns: INSERT INTO test_composer_key (id, name) VALUES (1, 'Mahler, Gustav') 1/COMMIT : auto 1/QueryOne: SELECT name FROM test_composer_key WHERE id = 1 1/QueryR : SELECT name FROM test_composer_key WHERE id = 1 1/COMMIT : auto ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-15 17:00:10
|
Patches item #1410834, was opened at 2006-01-20 15:21 Message generated for change (Comment added) made by linux4u You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: add RLIKE operator Initial Comment: Well, it looks like I'm inspired. I tried to do all the regular expression matching in python, but it was too slow, as I need to select records based on an expresion matching. So I have implemented RLIKE, also known as REGEXP or Posix Regular Expressions. You can use it as any other operator! mysql and firebird call it REGEXP and RLIKE postgres calls it ~ The rest just do not support it, so I've made it behave like "LIKE", as I did not find a standard manner not to support it. It's not a bad solution :) The patch is really trivial, I've tested it with many records (in mysql) and works as expected. I've tested the resulting SQL in postgres and it works too. Hope you can include it. ---------------------------------------------------------------------- >Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 18:00 Message: Logged In: YES user_id=140558 Let's see if you like this one. I've mcreated an own class for LIKE, moved it away from SQLOp and derived RLIKE from it. I pass all the tests and LIKE and RLIKE work a expected (tested in mysql), LIKE shoule still work in the rest of databases as the change is purely internal. For RLIKE I looked at the manuals, it should work AFAICT. We could even add REGEXP as another class effortlessly, but I'm not sure you want to have several way to do the same thing. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-13 20:26 Message: Logged In: YES user_id=4799 Take a look at INSubquery, NOTINSubquery, Subquery and EXISTS. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-13 19:37 Message: Logged In: YES user_id=140558 I tried to mimic LIKE as much as possible, that's why I did it this way. Moreover I could not find any example of doing it as you suggest. I had a look at the documentation and the generated SQL should be valid in all cases (REGEXP is also called RLIKE in mysql, I picked RLIKE to make it more natural, I also used REGEXP). If you could point me in the right direction, I could probably redo the patch as I'm aleady using it instead of direct use of SQL. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-13 17:39 Message: Logged In: YES user_id=4799 The patch is invalid. SQLObject renders SQLOp("RLIKE", expr) as "RLIKE " + expr. In SQLObject the operator is really called REGEXP, in Postgres ~. The patch tries to replace "RLIKE" to DBMS-specific name by replacing self.op (this is fragile by itself) but in a wrong time - in .execute(). Instead of SQLOp("RLIKE", expr) the thing should be implemented as a separate expression class, something like this: class RLIKE(SQLOp): def __sqlrepr__(self, db): ... ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-31 16:24 Message: Logged In: YES user_id=4799 There is much overlap between LIKE and RLIKE. Can you refactor it to remove duplicate code? ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-20 16:03 Message: Logged In: YES user_id=140558 Sorry, I attached the worng patch, this is the good one. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-15 15:55:07
|
Patches item #1353728, was opened at 2005-11-11 08:20 Message generated for change (Comment added) made by linux4u You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: define foreign keys in Style Initial Comment: I don't like to use attrID all along the code to access related tables, I want to be able use the nomeclature I like taking advantage of the nice Style idea. This is especially true when you create RelatedJoins when you use a nomeclature like I do (table.id_table), but it's the same for all the nomeclatures you can imagine. In styles.py it warns: def instanceAttrToIDAttr(self, attr): # @@: Right now, because of how names are created for foreign # keys, you can't really change this style. return attr + "ID" With this patch you can define how you want the foreign keys generated, they won't be mandatorily generated as attrID. Example: class LongStyle(Style): """ This style is derived from Style, that does not do any translation, but constructs the table ids like id_table. """ def instanceAttrToIDAttr(self, attr): return "id_" + attr def tableReference(self, table): # str.rsplit is python 2.4+ only if version_info >= (2, 4): return "id_" + table.rsplit(".", 1)[-1] else: return "id_" + rsplit(table, ".", 1)[-1] class mm_server(SQLObject): class sqlmeta: table = "smsarena.mm_server" style = LongStyle(longID = True) _connection = conn_smsarena server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") tz = StringCol(length = 20, default = 'CET', notNone = True) conutry_code = StringCol(length = 2, varchar = False, default = '', notNone = True) # until now I had to do this # mm_server_aliases = SQLMultipleJoin("mm_server_alias", joinColumn = "mm_serverID", orderBy = "server") # now it's perfect! mm_server_aliases = SQLMultipleJoin("mm_server_alias", orderBy = "server") class mm_server_alias(SQLObject): class sqlmeta: table = "smsarena.mm_server_alias" style = LongStyle(longID = True) _connection = conn_smsarena # until now I had to do this # mm_server = ForeignKey("mm_server", dbName = "id_mm_server") mm_server = ForeignKey("mm_server") server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") I hope it's clear :) Pau ---------------------------------------------------------------------- >Comment By: Pau Aliagas (linux4u) Date: 2006-02-15 16:54 Message: Logged In: YES user_id=140558 Ok, here I go again. I've fixed a small bug: the name of the field was not porperly set when using Key(foreignKey... instead of ForeignKey. This fixes test_basic. And I think that there is nothing else to fix, I'm probably wrong, but I'll explain it hera. test_auto_old.py... FAIL test_auto.py... FAIL test_foreignKey.py... FAIL These tests fail because sqlite is failing when adding columns. In mysql it does not fail. I do not think it's this patch fault. And finally: test_SQLMultipleJoin.py... FAIL E assert str(hibrid.fightersAsSResult.sum('power')) == '23' > assert '23.0' == '23' + where '23.0' = str(23.0) + where 23.0 = <Race 3 name="'hibrid (human wi...'">.fightersAsSResult.sum('power') Again this is an error in the test. Please let me know if it can go in now :) If you can have a quick look at it better, it takes time to restart ths tests, I'd rather do it before I move on to another thing. Thanks Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-14 10:05 Message: Logged In: YES user_id=140558 Oleg, I've posted to the list because I run the tests and pass. I'm sure I'm doing something wrong but I don't see what. I lost more than 3 hours yesterday just trying to run te tests :( I printed things in dbtest.py and say that TESTDB did not change anything. I chenged manually conftest.py because I ahd a message that yoiu need sqlite2 for memory databases, but still I'm not sure everything works becasue I pass al the tests. Can you help me, I want to close this patch soon and move to other improvements but this is being much more difficult than it should. Thanks a lot Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-09 17:42 Message: Logged In: YES user_id=140558 I'm very busy but again will try to find some time to fix it. I'm using it every day without a glitch, even using the clause attributes like in the Complex example (new type of joins *toMany). I'll update it to latest SVN just in case this is the problem, I did it with that day's current. Please do not close it, I really intend to pass the tests, I'm already using it. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-09 17:11 Message: Logged In: YES user_id=4799 test_auto.py, for example fails: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] l = [p.phone for p in Person.selectBy(name='tim')[0].phones] l.sort() E assert l == ['555-394-2930', '555-555-5555'] > assert [] == ['555-394-2930', '555-555-5555'] [sqlobject/tests/test_auto.py:61] ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 19:10 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 19:07 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-30 18:57 Message: Logged In: YES user_id=4799 test_auto.py, test_auto_old.py and test_basic.py failed. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 17:04 Message: Logged In: YES user_id=140558 This is the final patch against latest svn, it includes everything in one single patch. It passes the tests. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 14:17 Message: Logged In: YES user_id=140558 Ok, I have taken my time to understand pydist, test, etc, and here I am back with the working solution :) Now the resulting SQLobject passes all the tests. I attach an incremental patch so that you can see more clearly the changes done to fix the previous one. I've needed a new method in the Style class, instanceIDAttrToAttr, that is the complementary to the already known instanceAttrToIDAttr. If you need to transform back and forth field names, you need them both. I haven't tried to port it to the latest svn yet, this is against the same release than the first patch, but it should apply more or less clearly as this are very isolated areas in the code. When I do it I'll post it here. Sorry for the delay, it has not been easy for me to understand more deeply the code and, even less, to know how the tests work :) ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-03 13:18 Message: Logged In: YES user_id=140558 It fails because the test is not right, it still has the ID postfix hardcoded. My fault, I did no send a patch for tests. This is the piece that fails: # Select by usual way s = TestWorkKey.selectBy(composerID=c.id, title='Symphony No. 9') I have not looked at tests until now, but it looks like there should be tests for the different provides styles, in this case, if you accept the patch, at least a test for the LongStyle provided and for the current naming styles. I'll try to cook up something, but it can take a little time. Any guidelines will be appreciated (I've just read the docs ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-03 12:23 Message: Logged In: YES user_id=4799 test_selectBy_foreignKey.py fails: def test1(): setupClass([TestComposerKey, TestWorkKey]) c = TestComposerKey(name='Mahler, Gustav') > w1 = TestWorkKey(composer=c, title='Symphony No. 9') [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/tests/test_selectBy_foreignKey.py:19] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def __init__(self, **kw): # The get() classmethod/constructor uses a magic keyword # argument when it wants an empty object, fetched from the # database. So we have nothing more to do in that case: if kw.has_key('_SO_fetch_no_create'): return post_funcs = [] self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) # Pass the connection object along if we were given one. if kw.has_key('connection'): self._connection = kw['connection'] self.sqlmeta._perConnection = True del kw['connection'] self._SO_writeLock = threading.Lock() if kw.has_key('id'): id = self.sqlmeta.idType(kw['id']) del kw['id'] else: id = None > self._create(id, **kw) [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1210] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _create(self, id, **kw): self.sqlmeta._creating = True self._SO_createValues = {} self._SO_validatorState = SQLObjectState(self) # First we do a little fix-up on the keywords we were # passed: for column in self.sqlmeta.columnList: # Then we check if the column wasn't passed in, and # if not we try to get the default. if not kw.has_key(column.name) and not kw.has_key(column.foreignName): default = column.default # If we don't get it, it's an error: if default is NoDefault: E raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, column.name) > TypeError: TestWorkKey() did not get expected keyword argument composerID [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1231] - - - - - - - - - - - - - test1: recorded stdout - - - - - - - - - - - - - - 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/QueryR : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/QueryR : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/COMMIT : auto 1/Query : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/QueryR : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/COMMIT : auto 1/QueryIns: INSERT INTO test_composer_key (id, name) VALUES (1, 'Mahler, Gustav') 1/COMMIT : auto 1/QueryOne: SELECT name FROM test_composer_key WHERE id = 1 1/QueryR : SELECT name FROM test_composer_key WHERE id = 1 1/COMMIT : auto ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-15 14:22:14
|
Bugs item #1432190, was opened at 2006-02-15 15:22 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1432190&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Björn Lindqvist (sonderblade) Assigned to: Nobody/Anonymous (nobody) Summary: Table creation order for foreign key constraints Initial Comment: Note: I had to apply my patch in https://sourceforge.net/tracker/index.php?func=detail&aid=1432176&group_id=74338&atid=540674 otherwise the foreign key constrains would be completely ignored. I have a simple model.py file containing my two tables like this: class Network(SQLObject): name = StringCol(alternateID = True, length = 80) class Channel(SQLObject): network = ForeignKey("Network", notNull = True) name = StringCol() Using "tg-admin sql sql" produces a listing like this: CREATE TABLE channel ( id INT PRIMARY KEY AUTO_INCREMENT, network_id INT NOT NULL, name TEXT ); CREATE TABLE network ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(80) NOT NULL UNIQUE ); ALTER TABLE channel ADD CONSTRAINT channel_network_id_exists FOREIGN KEY (network_id) REFERENCES network (id); Creating these two tables manually work: Network.createTable() Channel.createTable() But when I try to create them using "tg-admin sql create" (which just wraps "sqlobject-admin create") I get the following exception: Traceback (most recent call last): File "/usr/bin/tg-admin", line 7, in ? sys.exit( File "/usr/lib/python2.4/site-packages/TurboGears-0.9a0dev_r778-py2.4.egg/turbogears/command/base.py", line 269, in main command.run() File "/usr/lib/python2.4/site-packages/TurboGears-0.9a0dev_r778-py2.4.egg/turbogears/command/base.py", line 129, in run command.the_runner.run(sys.argv) File "/usr/lib/python2.4/site-packages/SQLObject-0.8dev_r1596-py2.4.egg/sqlobject/manager/command.py", line 100, in run runner.run() File "/usr/lib/python2.4/site-packages/SQLObject-0.8dev_r1596-py2.4.egg/sqlobject/manager/command.py", line 231, in run self.command() File "/usr/lib/python2.4/site-packages/SQLObject-0.8dev_r1596-py2.4.egg/sqlobject/manager/command.py", line 583, in command tableConstraints = soClass.createTable() File "/usr/lib/python2.4/site-packages/SQLObject-0.8dev_r1596-py2.4.egg/sqlobject/main.py", line 1372, in createTable conn.query(constraint) File "/usr/lib/python2.4/site-packages/SQLObject-0.8dev_r1596-py2.4.egg/sqlobject/dbconnection.py", line 314, in query return self._runWithConnection(self._query, s) File "/usr/lib/python2.4/site-packages/SQLObject-0.8dev_r1596-py2.4.egg/sqlobject/dbconnection.py", line 228, in _runWithConnection val = meth(conn, *args) File "/usr/lib/python2.4/site-packages/SQLObject-0.8dev_r1596-py2.4.egg/sqlobject/dbconnection.py", line 311, in _query self._executeRetry(conn, conn.cursor(), s) File "/usr/lib/python2.4/site-packages/SQLObject-0.8dev_r1596-py2.4.egg/sqlobject/mysql/mysqlconnection.py", line 66, in _executeRetry return cursor.execute(query) File "/usr/lib/python2.4/site-packages/MySQLdb/cursors.py", line 137, in execute self.errorhandler(self, exc, value) File "/usr/lib/python2.4/site-packages/MySQLdb/connections.py", line 33, in defaulterrorhandler raise errorclass, errorvalue _mysql_exceptions.OperationalError: (1005, "Can't create table './test/#sql-1cf0_b9.frm' (errno: 150)") The problem is because sqlobject creates the Channel table before the Network table and therefore the query (despite the order that "tg-admin sql sql" seem to suggest): ALTER TABLE channel ADD CONSTRAINT channel_network_id_exists FOREIGN KEY (network_id) REFERENCES network (id); is executed before the Network table has been created. I think the problem can be solved by making it so all constraint statements are executed after the create table statements are executed. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1432190&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-15 14:04:27
|
Patches item #1432176, was opened at 2006-02-15 15:04 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1432176&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Björn Lindqvist (sonderblade) Assigned to: Nobody/Anonymous (nobody) Summary: redundant methods in sqlobject -> foreign keys don't work Initial Comment: There are some redundant methods dealing with foreign key constraints that I think was introduced lately into SQLObject. They make foreign key constraints not work on mysql-databases. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1432176&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-15 11:15:07
|
Patches item #1432091, was opened at 2006-02-15 12:15 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1432091&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Etienne Posthumus (epoz) Assigned to: Nobody/Anonymous (nobody) Summary: Handling array.array TEXT from MySQL results Initial Comment: For the UnicodeCol TEXT fields in a MySQL database, the results returned are not Strings but array.array. This patch to col.py enables the conversion to Unicode values. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1432091&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-15 10:56:12
|
Patches item #1432078, was opened at 2006-02-15 11:56 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1432078&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Etienne Posthumus (epoz) Assigned to: Nobody/Anonymous (nobody) Summary: Add DISTINCT to sqlbuilder.py Select Initial Comment: When using SQLBuilder do build database-independent queries, I would like to do DISTINCT queries. This already exists in normal SQLObject ClassName.select, but not in the builder. This tiny patch adds it. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1432078&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-15 06:31:34
|
Bugs item #1305062, was opened at 2005-09-26 13:07 Message generated for change (Comment added) made by nyenyec You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1305062&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: General Group: SQLObject release (specify) Status: Open Resolution: None Priority: 5 Submitted By: Andy Dustman (adustman) Assigned to: Nobody/Anonymous (nobody) Summary: 0.7a: RelatedJoin() glue table has no constraints Initial Comment: Consider the example from the online 0.6.1 documentation, with the User and Role objects, where each object does a RelatedJoin() to the other. This results in a glue table that looks like this: CREATE TABLE user_role ( user_id INT NOT NULL, role_id INT NOT NULL ) The schema lacks any FOREIGN KEY constraints, and a PRIMARY KEY. It should probalby look more like this: CREATE TABLE user_role ( user_id INT NOT NULL, CONSTRAINT user_id_exists FOREIGN KEY (user_id) REFERENCES user (id), role_id INT NOT NULL, CONSTRAINT role_id_exists FOREIGN KEY (role_id) REFERENCES role (id), PRIMARY KEY (user_id, role_id) ) ON DELETE CASCADE may be needed as well. Note that I am using patch #1299109 to add FOREIGN KEY support for MySQL. However, looking at join.py, it does not seem to do anything with foreign keys, so I do not think this is a dependency on MySQL; I think this behavior should be reproducable on other databases. The intermediate table schema is created in dbconnection.DBAPI._SO_createJoinTableSQL(), and it calls self.joinSQLType(join) to get the SQL for the column. In all the implementations (except Sybase which is slightly different), it returns 'INT NOT NULL' The table creation order looks like it could be a problem, as the glue/intermediate table seems to be created before the second of the other two tables, which would produce referential integrity problems (i.e.reference to a non-existent table). ---------------------------------------------------------------------- Comment By: nyenyec (nyenyec) Date: 2006-02-15 00:31 Message: Logged In: YES user_id=6142 This is still a problem in sqlobject 0.7.1dev-r1457 ---------------------------------------------------------------------- Comment By: Andy Dustman (adustman) Date: 2005-10-31 16:34 Message: Logged In: YES user_id=71372 BTW, the table creation order comment is really more of a problem for Turbogears. I've done a bit of testing by altering an existing glue table to use ON DELETE CASCADE and it seems to work as expected/desired. Without ON DELETE CASCADE, you have to delete the glue entry tables manually, (typically with obj.removeXXX(other_id)); otherwise your glue table has a bunch of dead entries, though if you have the FOREIGN KEY entry without ON CASCADE DELETE, then you can't remove the parent objects without first deleting the glue records. In other words, having FOREIGN KEY ... REFERENCES ... ON DELETE CASCADE keeps your glue table clean when you remove either object of the RelatedJoin(). ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1305062&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-14 09:05:08
|
Patches item #1353728, was opened at 2005-11-11 08:20 Message generated for change (Comment added) made by linux4u You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: define foreign keys in Style Initial Comment: I don't like to use attrID all along the code to access related tables, I want to be able use the nomeclature I like taking advantage of the nice Style idea. This is especially true when you create RelatedJoins when you use a nomeclature like I do (table.id_table), but it's the same for all the nomeclatures you can imagine. In styles.py it warns: def instanceAttrToIDAttr(self, attr): # @@: Right now, because of how names are created for foreign # keys, you can't really change this style. return attr + "ID" With this patch you can define how you want the foreign keys generated, they won't be mandatorily generated as attrID. Example: class LongStyle(Style): """ This style is derived from Style, that does not do any translation, but constructs the table ids like id_table. """ def instanceAttrToIDAttr(self, attr): return "id_" + attr def tableReference(self, table): # str.rsplit is python 2.4+ only if version_info >= (2, 4): return "id_" + table.rsplit(".", 1)[-1] else: return "id_" + rsplit(table, ".", 1)[-1] class mm_server(SQLObject): class sqlmeta: table = "smsarena.mm_server" style = LongStyle(longID = True) _connection = conn_smsarena server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") tz = StringCol(length = 20, default = 'CET', notNone = True) conutry_code = StringCol(length = 2, varchar = False, default = '', notNone = True) # until now I had to do this # mm_server_aliases = SQLMultipleJoin("mm_server_alias", joinColumn = "mm_serverID", orderBy = "server") # now it's perfect! mm_server_aliases = SQLMultipleJoin("mm_server_alias", orderBy = "server") class mm_server_alias(SQLObject): class sqlmeta: table = "smsarena.mm_server_alias" style = LongStyle(longID = True) _connection = conn_smsarena # until now I had to do this # mm_server = ForeignKey("mm_server", dbName = "id_mm_server") mm_server = ForeignKey("mm_server") server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") I hope it's clear :) Pau ---------------------------------------------------------------------- >Comment By: Pau Aliagas (linux4u) Date: 2006-02-14 10:05 Message: Logged In: YES user_id=140558 Oleg, I've posted to the list because I run the tests and pass. I'm sure I'm doing something wrong but I don't see what. I lost more than 3 hours yesterday just trying to run te tests :( I printed things in dbtest.py and say that TESTDB did not change anything. I chenged manually conftest.py because I ahd a message that yoiu need sqlite2 for memory databases, but still I'm not sure everything works becasue I pass al the tests. Can you help me, I want to close this patch soon and move to other improvements but this is being much more difficult than it should. Thanks a lot Pau ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-09 17:42 Message: Logged In: YES user_id=140558 I'm very busy but again will try to find some time to fix it. I'm using it every day without a glitch, even using the clause attributes like in the Complex example (new type of joins *toMany). I'll update it to latest SVN just in case this is the problem, I did it with that day's current. Please do not close it, I really intend to pass the tests, I'm already using it. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-09 17:11 Message: Logged In: YES user_id=4799 test_auto.py, for example fails: def test_dynamicJoin(self): col = KeyCol('personID', foreignKey='Person') Phone.sqlmeta.addColumn(col, changeSchema=True) join = MultipleJoin('Phone') Person.sqlmeta.addJoin(join) for phone in Phone.select('all'): if phone.phone.startswith('555'): phone.person = Person.selectBy(name='tim')[0] else: phone.person = Person.selectBy(name='bob')[0] l = [p.phone for p in Person.selectBy(name='tim')[0].phones] l.sort() E assert l == ['555-394-2930', '555-555-5555'] > assert [] == ['555-394-2930', '555-555-5555'] [sqlobject/tests/test_auto.py:61] ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 19:10 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-30 19:07 Message: Logged In: YES user_id=140558 I'll recheck it, it really passed all the tests applied to the latest svn. I tell you something tomorrow. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-30 18:57 Message: Logged In: YES user_id=4799 test_auto.py, test_auto_old.py and test_basic.py failed. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 17:04 Message: Logged In: YES user_id=140558 This is the final patch against latest svn, it includes everything in one single patch. It passes the tests. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-18 14:17 Message: Logged In: YES user_id=140558 Ok, I have taken my time to understand pydist, test, etc, and here I am back with the working solution :) Now the resulting SQLobject passes all the tests. I attach an incremental patch so that you can see more clearly the changes done to fix the previous one. I've needed a new method in the Style class, instanceIDAttrToAttr, that is the complementary to the already known instanceAttrToIDAttr. If you need to transform back and forth field names, you need them both. I haven't tried to port it to the latest svn yet, this is against the same release than the first patch, but it should apply more or less clearly as this are very isolated areas in the code. When I do it I'll post it here. Sorry for the delay, it has not been easy for me to understand more deeply the code and, even less, to know how the tests work :) ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-03 13:18 Message: Logged In: YES user_id=140558 It fails because the test is not right, it still has the ID postfix hardcoded. My fault, I did no send a patch for tests. This is the piece that fails: # Select by usual way s = TestWorkKey.selectBy(composerID=c.id, title='Symphony No. 9') I have not looked at tests until now, but it looks like there should be tests for the different provides styles, in this case, if you accept the patch, at least a test for the LongStyle provided and for the current naming styles. I'll try to cook up something, but it can take a little time. Any guidelines will be appreciated (I've just read the docs ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-03 12:23 Message: Logged In: YES user_id=4799 test_selectBy_foreignKey.py fails: def test1(): setupClass([TestComposerKey, TestWorkKey]) c = TestComposerKey(name='Mahler, Gustav') > w1 = TestWorkKey(composer=c, title='Symphony No. 9') [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/tests/test_selectBy_foreignKey.py:19] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def __init__(self, **kw): # The get() classmethod/constructor uses a magic keyword # argument when it wants an empty object, fetched from the # database. So we have nothing more to do in that case: if kw.has_key('_SO_fetch_no_create'): return post_funcs = [] self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) # Pass the connection object along if we were given one. if kw.has_key('connection'): self._connection = kw['connection'] self.sqlmeta._perConnection = True del kw['connection'] self._SO_writeLock = threading.Lock() if kw.has_key('id'): id = self.sqlmeta.idType(kw['id']) del kw['id'] else: id = None > self._create(id, **kw) [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1210] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def _create(self, id, **kw): self.sqlmeta._creating = True self._SO_createValues = {} self._SO_validatorState = SQLObjectState(self) # First we do a little fix-up on the keywords we were # passed: for column in self.sqlmeta.columnList: # Then we check if the column wasn't passed in, and # if not we try to get the default. if not kw.has_key(column.name) and not kw.has_key(column.foreignName): default = column.default # If we don't get it, it's an error: if default is NoDefault: E raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, column.name) > TypeError: TestWorkKey() did not get expected keyword argument composerID [/home/phd/work/SQLObject/SQLObject-patches/sqlobject/main.py:1231] - - - - - - - - - - - - - test1: recorded stdout - - - - - - - - - - - - - - 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_composer_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/QueryR : CREATE TABLE test_composer_key ( id SERIAL PRIMARY KEY, name TEXT ) 1/COMMIT : auto 1/QueryOne: SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/QueryR : SELECT COUNT(relname) FROM pg_class WHERE relname = 'test_work_key' 1/COMMIT : auto 1/Query : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/QueryR : CREATE TABLE test_work_key ( work_id SERIAL PRIMARY KEY, composer_id INT, title TEXT ) 1/COMMIT : auto 1/Query : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/QueryR : ALTER TABLE test_work_key ADD CONSTRAINT composer_id_exists FOREIGN KEY (composer_id) REFERENCES test_composer_key (id) 1/COMMIT : auto 1/QueryIns: INSERT INTO test_composer_key (id, name) VALUES (1, 'Mahler, Gustav') 1/COMMIT : auto 1/QueryOne: SELECT name FROM test_composer_key WHERE id = 1 1/QueryR : SELECT name FROM test_composer_key WHERE id = 1 1/COMMIT : auto ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-13 19:26:54
|
Patches item #1410834, was opened at 2006-01-20 17:21 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: add RLIKE operator Initial Comment: Well, it looks like I'm inspired. I tried to do all the regular expression matching in python, but it was too slow, as I need to select records based on an expresion matching. So I have implemented RLIKE, also known as REGEXP or Posix Regular Expressions. You can use it as any other operator! mysql and firebird call it REGEXP and RLIKE postgres calls it ~ The rest just do not support it, so I've made it behave like "LIKE", as I did not find a standard manner not to support it. It's not a bad solution :) The patch is really trivial, I've tested it with many records (in mysql) and works as expected. I've tested the resulting SQL in postgres and it works too. Hope you can include it. ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-02-13 22:26 Message: Logged In: YES user_id=4799 Take a look at INSubquery, NOTINSubquery, Subquery and EXISTS. ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-02-13 21:37 Message: Logged In: YES user_id=140558 I tried to mimic LIKE as much as possible, that's why I did it this way. Moreover I could not find any example of doing it as you suggest. I had a look at the documentation and the generated SQL should be valid in all cases (REGEXP is also called RLIKE in mysql, I picked RLIKE to make it more natural, I also used REGEXP). If you could point me in the right direction, I could probably redo the patch as I'm aleady using it instead of direct use of SQL. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-13 19:39 Message: Logged In: YES user_id=4799 The patch is invalid. SQLObject renders SQLOp("RLIKE", expr) as "RLIKE " + expr. In SQLObject the operator is really called REGEXP, in Postgres ~. The patch tries to replace "RLIKE" to DBMS-specific name by replacing self.op (this is fragile by itself) but in a wrong time - in .execute(). Instead of SQLOp("RLIKE", expr) the thing should be implemented as a separate expression class, something like this: class RLIKE(SQLOp): def __sqlrepr__(self, db): ... ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-31 18:24 Message: Logged In: YES user_id=4799 There is much overlap between LIKE and RLIKE. Can you refactor it to remove duplicate code? ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-20 18:03 Message: Logged In: YES user_id=140558 Sorry, I attached the worng patch, this is the good one. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-13 18:37:20
|
Patches item #1410834, was opened at 2006-01-20 15:21 Message generated for change (Comment added) made by linux4u You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Oleg Broytmann (phd) Summary: add RLIKE operator Initial Comment: Well, it looks like I'm inspired. I tried to do all the regular expression matching in python, but it was too slow, as I need to select records based on an expresion matching. So I have implemented RLIKE, also known as REGEXP or Posix Regular Expressions. You can use it as any other operator! mysql and firebird call it REGEXP and RLIKE postgres calls it ~ The rest just do not support it, so I've made it behave like "LIKE", as I did not find a standard manner not to support it. It's not a bad solution :) The patch is really trivial, I've tested it with many records (in mysql) and works as expected. I've tested the resulting SQL in postgres and it works too. Hope you can include it. ---------------------------------------------------------------------- >Comment By: Pau Aliagas (linux4u) Date: 2006-02-13 19:37 Message: Logged In: YES user_id=140558 I tried to mimic LIKE as much as possible, that's why I did it this way. Moreover I could not find any example of doing it as you suggest. I had a look at the documentation and the generated SQL should be valid in all cases (REGEXP is also called RLIKE in mysql, I picked RLIKE to make it more natural, I also used REGEXP). If you could point me in the right direction, I could probably redo the patch as I'm aleady using it instead of direct use of SQL. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-02-13 17:39 Message: Logged In: YES user_id=4799 The patch is invalid. SQLObject renders SQLOp("RLIKE", expr) as "RLIKE " + expr. In SQLObject the operator is really called REGEXP, in Postgres ~. The patch tries to replace "RLIKE" to DBMS-specific name by replacing self.op (this is fragile by itself) but in a wrong time - in .execute(). Instead of SQLOp("RLIKE", expr) the thing should be implemented as a separate expression class, something like this: class RLIKE(SQLOp): def __sqlrepr__(self, db): ... ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-31 16:24 Message: Logged In: YES user_id=4799 There is much overlap between LIKE and RLIKE. Can you refactor it to remove duplicate code? ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-20 16:03 Message: Logged In: YES user_id=140558 Sorry, I attached the worng patch, this is the good one. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-02-13 16:39:26
|
Patches item #1410834, was opened at 2006-01-20 17:21 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open >Resolution: Invalid Priority: 5 Submitted By: Pau Aliagas (linux4u) >Assigned to: Oleg Broytmann (phd) Summary: add RLIKE operator Initial Comment: Well, it looks like I'm inspired. I tried to do all the regular expression matching in python, but it was too slow, as I need to select records based on an expresion matching. So I have implemented RLIKE, also known as REGEXP or Posix Regular Expressions. You can use it as any other operator! mysql and firebird call it REGEXP and RLIKE postgres calls it ~ The rest just do not support it, so I've made it behave like "LIKE", as I did not find a standard manner not to support it. It's not a bad solution :) The patch is really trivial, I've tested it with many records (in mysql) and works as expected. I've tested the resulting SQL in postgres and it works too. Hope you can include it. ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-02-13 19:39 Message: Logged In: YES user_id=4799 The patch is invalid. SQLObject renders SQLOp("RLIKE", expr) as "RLIKE " + expr. In SQLObject the operator is really called REGEXP, in Postgres ~. The patch tries to replace "RLIKE" to DBMS-specific name by replacing self.op (this is fragile by itself) but in a wrong time - in .execute(). Instead of SQLOp("RLIKE", expr) the thing should be implemented as a separate expression class, something like this: class RLIKE(SQLOp): def __sqlrepr__(self, db): ... ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-01-31 18:24 Message: Logged In: YES user_id=4799 There is much overlap between LIKE and RLIKE. Can you refactor it to remove duplicate code? ---------------------------------------------------------------------- Comment By: Pau Aliagas (linux4u) Date: 2006-01-20 18:03 Message: Logged In: YES user_id=140558 Sorry, I attached the worng patch, this is the good one. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1410834&group_id=74338 |
|
From: <sub...@co...> - 2006-02-13 12:30:33
|
Author: phd
Date: 2006-02-13 05:30:18 -0700 (Mon, 13 Feb 2006)
New Revision: 1597
Modified:
home/phd/SQLObject/paramstyles/sqlobject/col.py
home/phd/SQLObject/paramstyles/sqlobject/events.py
home/phd/SQLObject/paramstyles/sqlobject/main.py
home/phd/SQLObject/paramstyles/sqlobject/manager/command.py
home/phd/SQLObject/paramstyles/sqlobject/mysql/mysqlconnection.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_SQLMultipleJoin.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_cache.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_string_id.py
Log:
Merged patches from the revisions 1589:1596 from the trunk
Modified: home/phd/SQLObject/paramstyles/sqlobject/col.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/col.py 2006-02-11 10:39:57 UTC (rev 1596)
+++ home/phd/SQLObject/paramstyles/sqlobject/col.py 2006-02-13 12:30:18 UTC (rev 1597)
@@ -752,8 +752,8 @@
'sTName': sTName})
return constraint
- def mysqlCreateSQL(self):
- sql = SOKeyCol.mysqlCreateSQL(self)
+ def mysqlCreateReferenceConstraint(self):
+ sTName = self.soClass.sqlmeta.table
other = findClass(self.foreignKey, self.soClass.sqlmeta.registry)
tName = other.sqlmeta.table
idName = other.sqlmeta.idName
@@ -766,18 +766,46 @@
action = 'ON DELETE RESTRICT'
else:
action = ''
- constraint = ('CONSTRAINT %(colName)s_exists '
+ constraint = ('ALTER TABLE %(sTName)s ADD CONSTRAINT %(sTName)s_%(colName)s_exists '
'FOREIGN KEY (%(colName)s) '
'REFERENCES %(tName)s (%(idName)s) '
'%(action)s' %
{'tName': tName,
'colName': self.dbName,
'idName': idName,
- 'action': action})
- sql = ', '.join([sql, constraint])
- return sql
+ 'action': action,
+ 'sTName': sTName})
+ return constraint
def mysqlCreateReferenceConstraint(self):
+ sTName = self.soClass.sqlmeta.table
+ other = findClass(self.foreignKey, self.soClass.sqlmeta.registry)
+ tName = other.sqlmeta.table
+ idName = other.sqlmeta.idName
+ if self.cascade is not None:
+ if self.cascade == 'null':
+ action = 'ON DELETE SET NULL'
+ elif self.cascade:
+ action = 'ON DELETE CASCADE'
+ else:
+ action = 'ON DELETE RESTRICT'
+ else:
+ action = ''
+ constraint = ('ALTER TABLE %(sTName)s ADD CONSTRAINT %(sTName)s_%(colName)s_to_%(tName)s '
+ 'FOREIGN KEY (%(colName)s) '
+ 'REFERENCES %(tName)s (%(idName)s) '
+ '%(action)s' %
+ {'tName': tName,
+ 'colName': self.dbName,
+ 'idName': idName,
+ 'action': action,
+ 'sTName': sTName})
+ return constraint
+
+ def mysqlCreateSQL(self):
+ return SOKeyCol.mysqlCreateSQL(self)
+
+ def mysqlCreateReferenceConstraint(self):
return None
def sybaseCreateSQL(self):
Modified: home/phd/SQLObject/paramstyles/sqlobject/events.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/events.py 2006-02-11 10:39:57 UTC (rev 1596)
+++ home/phd/SQLObject/paramstyles/sqlobject/events.py 2006-02-13 12:30:18 UTC (rev 1597)
@@ -79,7 +79,18 @@
Note: this is not called when an instance is created from an
existing database row.
"""
+class RowCreatedSignal(Signal):
+ """
+ Called after an instance is created, with the class as the
+ sender. Called with the arguments ``(kwargs, post_funcs)``.
+ There may be a ``connection`` argument. ``kwargs``may be usefully
+ modified. ``post_funcs`` is a list of callbacks, intended to have
+ functions appended to it, and are called with the arguments
+ ``(new_instance)``.
+ Note: this is not called when an instance is created from an
+ existing database row.
+ """
# @@: An event for getting a row? But for each row, when doing a
# select? For .sync, .syncUpdate, .expire?
Modified: home/phd/SQLObject/paramstyles/sqlobject/main.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/main.py 2006-02-11 10:39:57 UTC (rev 1596)
+++ home/phd/SQLObject/paramstyles/sqlobject/main.py 2006-02-13 12:30:18 UTC (rev 1597)
@@ -1273,7 +1273,11 @@
cache = self._connection.cache
cache.created(id, self.__class__, self)
self._init(id)
+ post_funcs = []
+ kw = dict([('class',self.__class__),('id',id)])
+ self.sqlmeta.send(events.RowCreatedSignal, kw, post_funcs)
+
def _SO_getID(self, obj):
return getID(obj)
Modified: home/phd/SQLObject/paramstyles/sqlobject/manager/command.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/manager/command.py 2006-02-11 10:39:57 UTC (rev 1596)
+++ home/phd/SQLObject/paramstyles/sqlobject/manager/command.py 2006-02-13 12:30:18 UTC (rev 1597)
@@ -1073,7 +1073,11 @@
if self.options.upgrade_to:
version_to = self.options.upgrade_to
else:
- version_to = os.path.basename(self.find_last_version())
+ fname = self.find_last_version()
+ if fname is None:
+ print "No version exists, use 'record' command to create one"
+ return
+ version_to = os.path.basename(fname)
current = self.current_version()
if v:
print 'Current version: %s' % current
Modified: home/phd/SQLObject/paramstyles/sqlobject/mysql/mysqlconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/mysql/mysqlconnection.py 2006-02-11 10:39:57 UTC (rev 1596)
+++ home/phd/SQLObject/paramstyles/sqlobject/mysql/mysqlconnection.py 2006-02-13 12:30:18 UTC (rev 1597)
@@ -18,6 +18,10 @@
self.db = db
self.user = user
self.password = password
+ if kw.has_key('client_encoding'):
+ self.client_encoding = col.popKey(kw, 'client_encoding')
+ else:
+ self.client_encoding = None
self.kw = {}
for key in ("unix_socket", "named_pipe", "init_command",
"read_default_file", "read_default_group"):
@@ -47,6 +51,8 @@
if hasattr(conn, 'autocommit'):
conn.autocommit(bool(self.autoCommit))
+ if self.client_encoding:
+ conn.query('SET NAMES ' + self.client_encoding)
return conn
@@ -98,9 +104,15 @@
def createColumn(self, soClass, col):
return col.mysqlCreateSQL()
+ def createReferenceConstraint(self, soClass, col):
+ return col.mysqlCreateReferenceConstraint()
+
def createIndexSQL(self, soClass, index):
return index.mysqlCreateIndexSQL(soClass)
+ def createReferenceConstraint(self, soClass, col):
+ return col.mysqlCreateReferenceConstraint()
+
def createIDColumn(self, soClass):
if soClass.sqlmeta.idType == str:
return '%s TEXT PRIMARY KEY' % soClass.sqlmeta.idName
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_SQLMultipleJoin.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_SQLMultipleJoin.py 2006-02-11 10:39:57 UTC (rev 1596)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_SQLMultipleJoin.py 2006-02-13 12:30:18 UTC (rev 1597)
@@ -40,4 +40,4 @@
assert saiyajin.fightersAsSResult.max('power') == 10
assert trunks in hibrid.fightersAsSResult
assert picollo not in hibrid.fightersAsSResult
- assert hibrid.fightersAsSResult.sum('power') == 23
+ assert str(hibrid.fightersAsSResult.sum('power')) == '23'
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_cache.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_cache.py 2006-02-11 10:39:57 UTC (rev 1596)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_cache.py 2006-02-13 12:30:18 UTC (rev 1597)
@@ -24,7 +24,7 @@
class CacheTest(SQLObject):
- name = StringCol(alternateID=True)
+ name = StringCol(alternateID=True, length=100)
def test_cache():
setupClass(CacheTest)
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_string_id.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_string_id.py 2006-02-11 10:39:57 UTC (rev 1596)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_string_id.py 2006-02-13 12:30:18 UTC (rev 1597)
@@ -5,7 +5,7 @@
class sqlmeta(sqlmeta):
idType = str
idName = 'test_id_here'
- name = StringCol()
+ name = StringCol(length=100)
def test_string_id():
conn = getConnection()
|