[web2py] Re: Wiki with Oracle?

2013-04-07 Thread Jason Phillips
The resolution of 
issue#1432https://code.google.com/p/web2py/issues/detail?id=1432 (submitted 
under my other account, I need to unify these) has now solved the first 
error you listed (*ORA-00904: WIKI_TAG.WIKI_PAGE: invalid identifier*), 
which was a IS_NOT_IN_DB query error of the type I described in the issue.

So I tested the wiki again in Oracle to see if I would still run into the 
second error you posted; I did, but can now add the full SQL queries that 
were generated.

For the Search page, the query looks like this:

SELECT DISTINCT COUNT(wiki_tag.wiki_page), wiki_page.id, wiki_page.slug, 
wiki_page.title, wiki_page.tags, wiki_page.can_read, wiki_page.body 
FROM (
  SELECT w_tmp.*, ROWNUM w_row FROM (
SELECT COUNT(wiki_tag.wiki_page), wiki_page.id, wiki_page.slug, 
wiki_page.title, wiki_page.tags, wiki_page.can_read, wiki_page.body 
FROM wiki_tag, wiki_page 
WHERE (((wiki_page.id = wiki_tag.wiki_page) AND (wiki_tag.name IN 
('stuff'))) OR (wiki_page.title LIKE (('%' || (REPLACE('stuff','%','%%')) 
|| '%' 
GROUP BY wiki_page.id, wiki_page.slug, wiki_page.title, wiki_page.tags, 
wiki_page.can_read, wiki_page.body 
ORDER BY COUNT(wiki_tag.wiki_page) DESC
  ) w_tmp WHERE ROWNUM=100
) wiki_tag, wiki_page  
WHERE (((wiki_page.id = wiki_tag.wiki_page) AND (wiki_tag.name IN 
('stuff'))) OR (wiki_page.title LIKE (('%' || (REPLACE('stuff','%','%%')) 
|| '%' AND w_row  0  
GROUP BY wiki_page.id, wiki_page.slug, wiki_page.title, wiki_page.tags, 
wiki_page.can_read, wiki_page.body 
ORDER BY COUNT(wiki_tag.wiki_page) DESC

There are two problems here. The larger problem not surprisingly occurs due 
to pagination, which I know has openly been acknowledged as a limitation 
with Oracle and the DAL:

Oracle also does not support pagination. It does not support neither the 
 OFFSET nor the LIMIT keywords. Web2py achieves pagination by translating a 
 db(...).select(limitby=(a,b)) into a complex three-way nested select (as 
 suggested by official Oracle documentation). *This works for simple 
 select but may break for complex selects involving aliased fields and or 
 joins*.


Indeed we do have a JOIN and pagination here. I've been looking at problems 
with the existing pagination solution and hope to find another way forward 
eventually (still using subqueries, but slightly modifying which conditions 
get written into the inner and outer queries); if I get somewhere, I'll 
certainly post my attempt.

But putting that aside for the moment, even when I remove the pagination 
(manually commented out to test), the query for this page gets generated 
incorrectly for Oracle:

SELECT DISTINCT COUNT(wiki_tag.wiki_page), wiki_page.id, 
wiki_page.slug,wiki_page
.title, wiki_page.tags, wiki_page.can_read, wiki_page.body 
FROM wiki_tag, wiki_page 
WHERE (((wiki_page.id = wiki_tag.wiki_page) AND (wiki_tag.name IN ('stuff'
))) OR (wiki_page.title LIKE (('%' || (REPLACE('stuff','%','%%')) || '%' 
GROUP BY wiki_page.id, wiki_page.slug, wiki_page.title, wiki_page.tags,wiki_page
.can_read, wiki_page.body 
ORDER BY COUNT(wiki_tag.wiki_page) DESC

The error returned is: *ORA-00932: inconsistent datatypes: expected - got 
CLOB*

The problem is that Oracle does not permit GROUP BY on columns of type 
CLOB; nor does it permit DISTINCT on these, for that is essentially another 
type of grouping. The CLOB columns in this table as defined include:
 
wiki_page.body
wiki_page.tags
wiki_page.html
wiki_page.can_read
wiki_page.can_edit

The query made for the page attempts to simultaneously fetch all the 
important information from the WIKI_PAGE table (including the full text of 
the post) *and* the count of matches in the WIKI_TAG table; to achieve 
this, it uses GROUP BY on all the WIKI_PAGE columns and then uses COUNT() 
on the WIKI_TAG entries. 

Here is the relevant wiki code:

count = db.wiki_tag.wiki_page.count()
fields = [db.wiki_page.id, db.wiki_page.slug,
  db.wiki_page.title, db.wiki_page.tags,
  db.wiki_page.can_read]
if preview:
fields.append(db.wiki_page.body)
if query is None:
query = (db.wiki_page.id == db.wiki_tag.wiki_page) \
(db.wiki_tag.name.belongs(tags))
query = query | db.wiki_page.title.contains(request.vars.q)
if self.settings.restrict_search and not self.manage():
query = query  (db.wiki_page.created_by == self.auth.
user_id)
*pages **= db(query).select(count,
*fields, **dict(orderby=orderby or ~count,
   groupby=reduce(lambda a, b: a | b, fields),
   distinct=True,
   limitby=limitby))*

Since the *wiki_page.tags* and *wiki_page.can_read *columns are also CLOBs, 
it won't help to disable preview and thereby skip the *body* column; 
grouping across CLOBs will persist as written.

From a general 

[web2py] Difficulty with auth.signature when renaming auth tables

2013-04-07 Thread Jason Phillips
When I follow what I thought to be standard practice (following this 
documentationhttp://www.web2py.com/books/default/chapter/29/09#Renaming-Auth-tables)
 
for using alternative names for the auth tables, I'm seeing an incorrect 
foreign key reference on any subsequent table defined that uses 
auth.signature.

Here's the basic test code in a db.py:

auth = Auth(db)

auth.settings.table_user_name = 'cst_user'
auth.settings.table_group_name = 'cst_group'
auth.settings.table_membership_name = 'cst_membership'
auth.settings.table_permission_name = 'cst_permission'
auth.settings.table_event_name = 'cst_event'
auth.settings.table_cas_name = 'cst_cas'

auth.define_tables(username=True,signature=False)

db.define_table('tmp_mytable',
  Field('something'),
  auth.signature)



This works so far as the auth tables are concerned; web2py creates them 
with the alternate names specified, properly referencing each other. 

However, the query generated to create the subsequent table that uses 
auth.signature (*tmp_mytable* above) refers in its foreign key declaration 
to the standard auth table names instead. The query below was generated 
(using SQLITE to test, though I first encountered this with Oracle).


CREATE TABLE mytable(
id INTEGER PRIMARY KEY AUTOINCREMENT,
something CHAR(512),
is_active CHAR(1),
created_on TIMESTAMP,
created_by INTEGER REFERENCES auth_user (id) ON DELETE CASCADE,
modified_on TIMESTAMP,
modified_by INTEGER REFERENCES auth_user (id) ON DELETE CASCADE
);

Note that it has reverted to the default name auth_user for the 
referenced foreign keys. What am I doing wrong here? 

(Version 2.4.5-stable+timestamp.2013.04.06.10.09.56)

-- 

--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




[web2py] Re: Difficulty with auth.signature when renaming auth tables

2013-04-07 Thread Jason Phillips
Thank you so much, that solved it. 

(It might be helpful to others if that important caveat makes it into the 
relevant 
section of 
documentationhttp://www.web2py.com/books/default/chapter/29/09#Renaming-Auth-tables
 at 
some point, though I know that not every detail can be explained succinctly 
there.)


On Sunday, April 7, 2013 7:29:00 PM UTC-5, Anthony wrote:

 Looks like by default, auth.signature gets defined when Auth is 
 initialized, which is before you have set the custom table names. To avoid 
 this do:

 auth = Auth(db, signature=False)

 In that case, auth.signature will instead be defined when you call 
 auth.define_tables(), by which point the custom tables names will already 
 be set.

 Anthony

 On Sunday, April 7, 2013 6:58:09 PM UTC-4, Jason Phillips wrote:

 When I follow what I thought to be standard practice (following this 
 documentationhttp://www.web2py.com/books/default/chapter/29/09#Renaming-Auth-tables)
  
 for using alternative names for the auth tables, I'm seeing an incorrect 
 foreign key reference on any subsequent table defined that uses 
 auth.signature.

 Here's the basic test code in a db.py:

 auth = Auth(db)

 auth.settings.table_user_name = 'cst_user'
 auth.settings.table_group_name = 'cst_group'
 auth.settings.table_membership_name = 'cst_membership'
 auth.settings.table_permission_name = 'cst_permission'
 auth.settings.table_event_name = 'cst_event'
 auth.settings.table_cas_name = 'cst_cas'

 auth.define_tables(username=True,signature=False)

 db.define_table('tmp_mytable',
   Field('something'),
   auth.signature)



 This works so far as the auth tables are concerned; web2py creates them 
 with the alternate names specified, properly referencing each other. 

 However, the query generated to create the subsequent table that uses 
 auth.signature (*tmp_mytable* above) refers in its foreign key 
 declaration to the standard auth table names instead. The query below was 
 generated (using SQLITE to test, though I first encountered this with 
 Oracle).


 CREATE TABLE mytable(
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 something CHAR(512),
 is_active CHAR(1),
 created_on TIMESTAMP,
 created_by INTEGER REFERENCES auth_user (id) ON DELETE CASCADE,
 modified_on TIMESTAMP,
 modified_by INTEGER REFERENCES auth_user (id) ON DELETE CASCADE
 );

 Note that it has reverted to the default name auth_user for the 
 referenced foreign keys. What am I doing wrong here? 

 (Version 2.4.5-stable+timestamp.2013.04.06.10.09.56)



-- 

--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.