Again: virtual field requires type-attribute

485 views
Skip to first unread message

Martin Weissenboeck

unread,
Feb 26, 2013, 2:33:22 AM2/26/13
to web...@googlegroups.com
I have tried another model:

db.define_table('test',
    Field('t1'),
    Field('t2'),
    )
db.test.c12 = Field.Virtual (lambda r: r.t1+r.t2)

And i get:

<type 'exceptions.AttributeError'> 'FieldVirtual' object has no attribute 'type'

Version

web2py™(2, 4, 1, 'alpha.2', datetime.datetime(2013, 2, 17, 11, 27, 22))
PythonPython 2.7.1

: H:\Python27\python.exe (prefix: H:\Python27)


What is wrong?
Regards, Martin


Donatas Burba

unread,
Feb 26, 2013, 6:28:59 AM2/26/13
to web...@googlegroups.com, mar...@weissenboeck.at
I have a workaround for this issue. Just a little helper function in modules:

def virtual_field(db, table_name, field_name, field_type, compute=lambda row: None, label='', represent=None):
    db[table_name][field_name] = Field.Virtual(compute)
    db[table_name][field_name].type = field_type
    db[table_name][field_name].label = label
    db[table_name][field_name].represent = represent
    db[table_name][field_name].formatter = lambda value: value
    db[table_name][field_name].comment = None
    db[table_name][field_name].readable = True
    db[table_name][field_name].writable = False
    db[table_name][field_name].requires = None
    db[table_name][field_name].widget = None
    db[table_name][field_name].name = field_name
    db[table_name][field_name].tablename = table_name
    db[table_name][field_name].filter_out = None

Because I very often need such virtual fields (to show complex computed result from several fields or even tables), this really helps me.

Massimo Di Pierro

unread,
Feb 26, 2013, 12:42:23 PM2/26/13
to web...@googlegroups.com, mar...@weissenboeck.at
This helped me a lot. I included these defaults in web2py so that you should need to do it yourself. Can you please check if 

db.test.c12 = Field.Virtual (lambda r: r.t1+r.t2)

now works as expected?

Martin Weissenboeck

unread,
Feb 26, 2013, 3:43:15 PM2/26/13
to web...@googlegroups.com
Sorry, no - same message.
I have taken the last version from trunk one hour ago.

Ticket ID

127.0.0.1.2013-02-26.21-39-35.e1477239-8991-4217-810f-9e320daf692c

<type 'exceptions.AttributeError'> 'FieldVirtual' object has no attribute 'type'

Version

web2py™ (2, 4, 1, 'alpha.2', datetime.datetime(2013, 2, 25, 23, 19, 14))
Python Python 2.7.3: D:\Python27\python.exe (prefix: D:\Python27)

Traceback


1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.

Traceback (most recent call last):
File "D:\web2py\gluon\restricted.py", line 212, in restricted
exec ccode in environment
File "D:/web2py/applications/calctest/controllers/default.py", line 88, in <module>
File "D:\web2py\gluon\globals.py", line 193, in <lambda>
self._caller = lambda f: f()
File "D:/web2py/applications/calctest/controllers/default.py", line 16, in t
db.test.c12,
File "D:\web2py\gluon\dal.py", line 9754, in select
return adapter.select(self.query,fields,attributes)
File "D:\web2py\gluon\dal.py", line 2218, in select
return super(SQLiteAdapter, self).select(query, fields, attributes)
File "D:\web2py\gluon\dal.py", line 1665, in select
sql = self._select(query, fields, attributes)
File "D:\web2py\gluon\dal.py", line 1520, in _select
sql_f = ', '.join(map(geoexpand, fields))
File "D:\web2py\gluon\dal.py", line 1517, in geoexpand
if isinstance(field.type,str) and field.type.startswith('geometry'):
AttributeError: 'FieldVirtual' object has no attribute 'type'



2013/2/26 Massimo Di Pierro <massimo....@gmail.com>

--
 

Massimo Di Pierro

unread,
Feb 26, 2013, 4:07:13 PM2/26/13
to web...@googlegroups.com, mar...@weissenboeck.at
I get:

$ python web2py.py -S welcome
Version 2.4.1-alpha.2+timestamp.2013.02.26.11.40.15
Database drivers available: SQLite(sqlite3), MySQL(pymysql), PostgreSQL(pg8000), IMAP(imaplib)
WARNING:web2py:import IPython error; use default python shell
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> db.define_table('test',
...     Field('t1'),
...     Field('t2'),
...     )
<Table test (id,t1,t2)>

Martin Weissenboeck

unread,
Feb 26, 2013, 4:44:43 PM2/26/13
to web...@googlegroups.com
My try:


db.define_table('test',
    Field('t1'),
    Field('t2'),
    )
   
db.test.c12 = Field.Virtual (lambda r: r.t1+r.t2)

def t():
    return dict(f=db(db.test.id>0).select(
        db.test.c12,
        ),
        c=db.test(1).c12,
        )

New version, new message:

Ticket ID

127.0.0.1.2013-02-26.22-38-37.30eb0659-ae50-4985-b105-f7303ce6b911

<class 'sqlite3.OperationalError'> near "<": syntax error

Version

web2py™ (2, 4, 1, 'alpha.2', datetime.datetime(2013, 2, 26, 11, 40, 15))
Python Python 2.7.3: D:\Python27\python.exe (prefix: D:\Python27)

--
 
---
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+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Martin Weissenboeck

unread,
Feb 26, 2013, 4:46:58 PM2/26/13
to web...@googlegroups.com
And here is the full traceback:

Traceback


1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.

Traceback (most recent call last
):
File "D:\dropbox\InfoSMS\web2py\gluon\restricted.py", line 212, in restricted
exec ccode in environment
File "D:/dropbox/InfoSMS/web2py/applications/calctest/controllers/default.py", line 91, in <module>
File "D:\dropbox\InfoSMS\web2py\gluon\globals.py", line 193, in <lambda>
self._caller = lambda f: f
()
File "D:/dropbox/InfoSMS/web2py/applications/calctest/controllers/default.py", line 19, in t
db.test.e12,
File "D:\dropbox\InfoSMS\web2py\gluon\dal.py", line 9765, in select
return adapter.select(self.query,fields,attributes)
File "D:\dropbox\InfoSMS\web2py\gluon\dal.py", line 2218, in select

return super(SQLiteAdapter, self).select(query, fields, attributes
)
File "D:\dropbox\InfoSMS\web2py\gluon\dal.py", line 1678, in select
return self._select_aux(sql,fields,attributes)
File "D:\dropbox\InfoSMS\web2py\gluon\dal.py", line 1643, in _select_aux
self.execute(sql)
File "D:\dropbox\InfoSMS\web2py\gluon\dal.py", line 1756, in execute
return self.log_execute(*a, **b)
File "D:\dropbox\InfoSMS\web2py\gluon\dal.py", line 1750, in log_execute
ret = self.cursor.execute(*a, **b)
OperationalError: near "<": syntax error

Error snapshot help

<class 'sqlite3.OperationalError'>(near "<": syntax error)




2013/2/26 Martin Weissenboeck <mwei...@gmail.com>

Massimo Di Pierro

unread,
Feb 26, 2013, 5:12:19 PM2/26/13
to web...@googlegroups.com, mar...@weissenboeck.at
>>> db = DAL()
>>> db.define_table('test',Field('t1'),Field('t2'))
<Table test (id,t1,t2)>
>>> db.test.c12 = Field.Virtual (lambda r: r.test.t1+r.test.t2)
>>> db.test.insert(t1='x',t2='y')
1L
>>> db.test(1).c12
'xy'

Notice:

db.test.c12 = Field.Virtual (lambda r: r.test.t1+r.test.t2)

not 

db.test.c12 = Field.Virtual (lambda r: r.t1+r.t2)

Moreover this is not valid:

db(db.test.id>0).select(db.test.c12)

you cannot select a virtual field from database. You can select the fields required to compute the virtual fields:

db(db.test.id>0).select(db.test.t1, db.test.t2)

and you get virtual field automatically:

for row in db(db.test.id>0).select(db.test.t1, db.test.t2): print row.c12

Martin Weissenboeck

unread,
Feb 26, 2013, 6:06:14 PM2/26/13
to web...@googlegroups.com
Thank you for your help - now it works perfect!

Julio del Barrio

unread,
Jul 19, 2016, 3:54:10 PM7/19/16
to web2py-users
Hi, Massimo.
If I not want any virtual fields in row object returned by select? If I use the row as dict in a insert operation, I must to filter, and I haven't any way to know what field is virtual, in abstract.

Massimo Di Pierro

unread,
Jul 25, 2016, 1:59:18 PM7/25/16
to web2py-users
In select(....) you can pass the list of fields that you want. Are you asking for an automated way to exclude virtual fields?

Anthony

unread,
Jul 26, 2016, 12:30:17 PM7/26/16
to web2py-users
On Tuesday, July 19, 2016 at 3:54:10 PM UTC-4, Julio del Barrio wrote:
Hi, Massimo.
If I not want any virtual fields in row object returned by select? If I use the row as dict in a insert operation, I must to filter, and I haven't any way to know what field is virtual, in abstract.

If using an existing Row or dictionary in an insert, you should use the ._filter_fields method (which will also filter out the "id" field):

db.mytable.insert(**db.mytable._filter_fields(row))

Anthony
Reply all
Reply to author
Forward
0 new messages