you may read about CREATE TABLE dialects:
How To Create a User-Defined Service on MS windows
<a
How To Create a User-Defined Service on MS windows
<a
Leave a Comment » | Helpful tutorials | Tagged: 'direct to disk file upload', 'uri schemes', abstraction, access, allow, Array, cache, cheat, concept, conditional, control, dal, database, datetime, decorator, direct, disk, eval(), extensions, fastcgi, Get, hosting, HTTP, javascript, jquery, jsonp, layer, library, lighthttpd, many, mapping, mercurial, object, origin, pass, passing, pubsub, python, relational, rest, service, sheet, standard, timeout, to, upload, web2py, webfaction, windows, wsgi | Permalink
Posted by web2py
import urllib data=urllib.urlopen('http://localhost:8001/myscript.cgi? parameter=value')
You can read more in the urllib and urllib2 documentation).
You cannot call the cgi scripts from web2py without going over HTTP.
This is not a web2py limitation, this is a CGI one. In fact CGI
assumes that every CGI script is executed in its own process and thus
has its own folder, environment variables and stdout/stdin. Therefore
a CGI script is not thread safe and cannot be executed inside a
thread (threads shares folder, environment and IO streams). web2py
uses threads.
## uuid.py import random,time def uuid4(): return '%s%s" % (int(time.time()),random.randint(100000,999999)) ## end file
cd web2py python web2py.py -S application_name -M # -M means to import also all the models in the application
and congratulations, you can do something like:
print db.tables
to get list of all database tables used by this application.
You can ofcourse do more .
In fact one of the interesting stuff that you can make is:
python web2py.py -S application_name -M -R file.py
the interesting thing is that file.py can include code that will be executed as if it were a part of a controller.
If the application specified by -S doesn’t exist, shell offers you to create it. isn’t that cool? 😀
you can also import your custom modules and use it inside shell:
exec('from applications.%s.modules.my_custom_mod import *' %(request.application))
Your module will run in its own context, so if you want to do some operations like manipulating request, or some database stuff, you have to pass those objects to your module functions or class explicitly when calling them, this implies of course that you define your functions or classes with that in mind
class DoThat(object): def __init__(self, request, db, cache, T): ..... ......
To execute a model file of another application:
[soucecode]
execfile(os.path.join(request.folder,’../other/app/models/db.py’))
[/sourcecode]
You can use the previous mechanism to execute other application controllers but there may be issues in importing controllers in other ways since they may contain authorization code outside functions. and it’s not a good idea to import controllers .
you can even run the shell without ipython if you just don’t want it
simply pass the -P (uppercase) argument when trying to run the shell.
Warning:
In the shell you have to explicitly db.commit() or db.rollback() your transactions.
response.cookies[response.session_id_name].secure=True
The secure cookies are not enabled by default because admins usually access the admin application through their lcalhost, but it you’re tending to access it remotely you should add secure cookies.
If somebody intercept your communications and steals the session
cookies for admin, they can become admin.
These rules apply to web2py as well as to every system that does
authentication. even gmail has this problem.
To make things even more secure admin session is default to expire after 10 minutes.
form.components[0].components[0].components[1]
or you can deal with forms as list of lists and edit its components according to your needs [just print a form and youi’ll know how to access it using this method.
form[0][..][..]
Warning:
It is never a good idea to access form components since the internal
implementation may change in the future (Although there ‘re no plans to do so).
you can access them that way if there’s no other way to do so.
To create your tables, you may either do it manually or use a web based tool for this purpose.
It’s able to generate web2py’s DAL compatible code.
This great tool can’t be a part of web2py framework itself because its license conflicts with web2py’s license that have an exception to ship the binary web2py code with your web applications without the source code as long as you didn’t touch the source code .
You can’t use controller functions in another controller because technically controller is not a module.
you need to gather all your common functions,and put them inside a model or module, or even in gluon.contrib so that they can be accessible to all your applications without no problem
When a request comes to a controller the requested controller file is loaded this is not achieved using reload() but exec() which executes the controller file and only takes about 0.03 seconds only.
Using exec() also has the advantage that the framework does not
need to monitor modules for changes before reloading (like Pylons)
which may cause a slow down for apps with multiple files. web2py only
execs those controllers that are requested.
For framework like django, application is just the reuse unit, but not the execution unit. And in web2py app is execution unit, but
not reuse unit. For example, I have user management app, and I want to reuse it, in Django, I can import the user model, user controller
functions, and use template also. But in web2py I can’t directly
import and reuse them. Only I can think out is copy the file which I
want to use to target app. There are many ways to combine different apps together, but the usage of exec make it difficult. And how to orginaze the development unit and execution unit is a design issue. If we only care about the execution unit, so how to use others app functionalities in our app? Only through xml-rpc? Or copy the files into the application.
In the contrary:
There are also other problems with modules related to the search path
and different applications may end up with conflicting modules.
There may also be conflicting classes because all modules would be
imported in the same context and if two modules have classes with the
same name they would overwrite each other. This is not an issue if one just made an import like:
from app1 import Class1 from app2 import Class1
Now you can use app1.Class1 or app2.Class1 wihtout any problems.
In web2py exec() behavior is similar to:
For example:
a=""" class A: name='a' print A.name """ b=""" class A: name='b' print A.name """ c={} exec(a,{},c) exec(b,{},{}) exec('print A.name',{},c) prints a b a
which is nice: the two classes called A ignore each other. If you use
modules you end up with a lot of potential conflicts between multiple
apps. In Django for example you would have to careful in designing
apps that do not conflict. In web2py you do not need to think about
it. You have to do a little of extra work to share stuff but at least
you know for sure that no unwanted sharing takes place.
the ‘exec’ have a good thing , that is the module can be GC by python afte request is over.
sometimes you need to call some controllers functions and pass to them some variables[request variables] to make some functionality based on the values of these variables.In this case you may face one or more situations like those:
URL(r=request, c='controller_name', args=[...], vars=dict(..=.., ..=..))
args are list why ? It allows you to do ‘/’.join(request.args) and rebuild the original string easily.
vars is a dictionary why ? because this is the best fit for it key/value pairs .
example:
Warning: This’s just an example made for test purposes to clarify things.
Assume application name is ‘t2’
def index(): return dict(url=A('click here', _href=URL(r=request, f='another', args=['a'], vars=dict(b='b')))) def another(): print response._caller(another) import urllib2, urllib if request.args(0) and request.vars.has_key('b'): test_values = {'hidden_var' : 1} data = urllib.urlencode(test_values) try: req = urllib2.urlopen('http://127.0.0.1/t2/default/third?%s'%data).read() return dict(x=XML(req)) except Exception, e: print 'Error:', e def third(): form = SQLFORM(db.my_table, request.vars.hidden_var) if form.accepts(request.vars, session): pass return form
whenever you want to import something from a module don’t do something like:
from applications.yourapp.modules.Custom_Validators import IS_AAA
making your import dependent on the name of the app is not a good idea, instead use something like:
exec('from applications.%s.modules.validators import IS_AAA' % request.application)
Nothing breaks except that you can no longer visit pages that you do
not have. You only get an internal error if you try to do that.
welcome.tar is the scaffold application. That’s the one file you
should not remove.
Notice that if you remove admin you can no longer login as
administrator and the database administration (appadmin) will be
disabled for all you apps, unless you adit the appadmin.py files and
change the authentication mechanism.
You may need to rename your applicationa ‘init’, so that it can be the default application (the one that starts, once you start web2py) .
T("bla")+T("bla")
but it does allow :
T("bla %(name)s",dict(name='Tim'))
why?
@auth.requires_login() @auth.requires_memebrship('admin') def do_it(): # This won't be executed unless user is logged in and belongs to the 'admin' group
Web2py philosophy is not to use decorators for validation since decorators are associated to a function (i.e. a page) while validation is associated to a form (and a page can have multiple forms).
A form should be an object that knows how to validate itself.
#in a model: db.define_table('my_table', Field('my_field', 'string' ,requires=[....])) #in a controller form = SQLFORM(db.my_Table) .........................................
user_input -> validator -> data_for_db OR error user_output <- validator <- data_from_db
IS_DATE('%Y-%m-%d') OR IS_DATE('%d-%m%Y')
This cannot be.
To understand this well, consider this example:
consider IS_DATE
it has a constructor a __call__() method and a formatter method,
when data is validated in a form it is filtered by IS_DATE.__call__
and a string, say ’01/01/2007′ is converted to a datetime object.
when data is presented into an edit SQLFORM or a SQLTABLE, formatter , it is called and the datetime object is converted back to ’01/01/2007′.
The constructor takes an argument that specifies how the formatter
can be done.
If you have a list of validators and they all pass the the __call__
method, they are called in the order of the list and the formatter methods are called in reversed order.
Not so many validators use formatter method, but the problem is that : wil this continue for ever ?
People can write validators that take formatter method and thus using OR will be problematic.
IS_EMPTY_OR(IS_URL())
{{=BEAUTIFY(response._Vars)}}
Web2py can supports both POST and GET variables together sent with each other and you can extract each set.
request.post_vars, request.get_vars
Web2py takes care of the situations like when MS-Windows user input data which will be sent with ‘\r’ in the end of your input [‘\n\r’ is the line terminator in windows but not in linux .. In linux it’s just ‘\n’] .any way user input will have to be filtered using something like:
string.replace('\r', '')
{{extend 'layout.html'}} {{""" You should not modify this file. It is used as default when a view is not provided for your controllers """}} {{=BEAUTIFY(response._vars)}} <button onclick="document.location='{{=URL("admin","default","design", args=request.application)}}'">admin</button> <button onclick="jQuery('#request').slideToggle()">request</button> <div class="hidden" id="request"><h2>request</h2>{{=BEAUTIFY(request)}}</div> <button onclick="jQuery('#session').slideToggle()">session</button> <div class="hidden" id="session"><h2>session</h2>{{=BEAUTIFY(session)}}</div> <button onclick="jQuery('#response').slideToggle()">response</button> <div class="hidden" id="response"><h2>response</h2>{{=BEAUTIFY(response)}}</div> <script>jQuery('.hidden').hide();</script>
this stuff is useful in development time since it gives you buttons to check session variables, request and response but in production you may just make it look like:
{{extend 'layout.html'}} {{=BEAUTIFY(response._vars.values())}}
and bingoo !!!!!! you get every thing almost automated and you don’t need to add one view file per action .
Ofcourse this is not practical all the time , and in real-life you always have some thing to add to the view but sometimes you don’t have 🙂
and you can rely on the generic.html then to render your view.
def test(): response.flash=T('Welcome to web2py') response.view='default/view.html' ### this indicates the view file return dict(message=T('Hello World')) #Here's the same version of the function but more suitable for caching the view . @cache(request.env.path_info, time_expire=5, cache_model=cache.ram) def test(): response.flash=T('Welcome to web2py') response.view='default/view.html' return response.render(dict(message=T('Hello World')))
{{if reponse._vars.has_key('form'):}} # or {{if form:}}
def index(): form = FORM(INPUT(_name='Name'), INPUT(_type='submit')) if form.accepts(request.vars, session): pass return dict(form=form)
Now trying to access page as index.html will return the form as expected, but trying to access index.xml will return something like:
<document> − <form> <form action="" enctype="multipart/form-data" method="post"><input name="Name" type="text" /><input type="submit" /><div class="hidden"><input name="_formkey" type="hidden" value="43ab2943-2f1c-4ae6-bdaf-73e3224967ee" /><input name="_formname" type="hidden" value="default" /></div></form> </form> </document>
Can you see the beauty of this? You can use similar behaviors for debugging without trying to print the form itself in your code.
Faster right ? easier right ? 😀
if fieldtype=='blob': obj=base64.b64encode(str(obj))
web2py is not currently using blobs by the book. The reason is that
blob values need to be escaped differently by different database
backends and in some cases this is not well documented. web2py avoids
the problem by storing the base64 encoded data, thus using the blob
as a text field.
The current behavior has both advantages (simpler code, faster encoding, humanly readable SQL string all the time, works with databases that may not have a blob type) and disadvantages (the storage is increased by 30%, you cannot search with LIKE,, in a blob).
Field('blobf','blob') # Not Recommended Field('uploadf','upload') # Reommended
- Not to separate between production and debugging modes.
- It is conceptually possible to cause bad errors that Web2py
may not be able to read the file that contains the error and even
requires web2py restart.- No configuration files for the framework itself, but you can make your own configuration file for your web application.
{{if x > 6:}} {{do_some_thing}} {{else:}} {{pass}}
session.table = db.my_table # Don't do this
SQLDB objects are not pickleble because of the open connection.
In fact you cannot store objects that belong to a class starting with SQL*, i.e. connections, record sets, queries, individual records, etc. You also cannot store classes (only objects), functions and lambdas.
[classes starting with SQL like SQLFIELD are having short names now like Field, ….. both names are working in fact ]
user = db(db.users.username==username).select().first()
You cannot store a user object in the session.The reason is that user has a method user.update_record which requires a db connection and it is not serializable.
If cPickle.dumps(obj) does not raise an exception than you can do
session.obj=obj
if form.accepts(request.vars, session)
This mechanism fail though if you’ve multiple forms in the same page
and in this case we should pass to the accepts function of every form explicit and different form names to distinguish between forms when they’re being accepted.
if form1.accepts(request.vars, formname='custom_name'): #do_something if form2.accepts(request.vars, formname='custom_name2'): #do_another thing
Any way the new Google appengine Bigtable datastore makes any SQL-based ORMs moot now anyway, so all we really need to worry about are the business logic and presentation, both of which web2py excels at.
To change this [may be in a real production mode], you’ve to change one line in models/db.py from
db = DAL('sqlite://storage.sqlite')
into the appropriate dbms url in your system, for example to support mysql you simply have to do :
'mysql://username:password@localhost/test'
db = DAL(None)
then you can define tables, and create SQLFORMs from those tables and test the validation mechanism
and generate the real sql queries generated by DAL and that are hidden by the DAL syntax
# Model db = DAL(None) db.define_table('members', Field('name', requires=IS_NOT_EMPTY())) #Controller def index(): form = SQLFORM(db.members) if form.accepts(request.vars, session): response.flash = T('hey it worked') rows=db().select(db.members.ALL) print db._lastsql return dict(form=form)
Congratulations !!! without need to introduce extra/new syntax.
Internally DAL(None) behaves like a sqlite db and you can use it test query generations as well but there is no sqlite file so nothing is stored and no overhead.
Things to take care of when using sqlite though are :
If you want to make more complex changes in the structure of a table, you will have to recreate the table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.
For example, suppose you have a table named “t1” with columns names “a”, “b”, and “c” and that you want to delete column “c” from this table. The following steps illustrate how this could be done:
BEGIN TRANSACTION; CREATE TEMPORARY TABLE t1_backup(a,b); INSERT INTO t1_backup SELECT a,b FROM t1; DROP TABLE t1; CREATE TABLE t1(a,b); INSERT INTO t1 SELECT a,b FROM t1_backup; DROP TABLE t1_backup; COMMIT;
db.define_table('my_table', Field('my_field', .....), migrate=True) # migrate=True
setting migrate to True comes in rescue in the development time, you can just change the structure of your table [add more fields, remove ones] and your changes will take effect on the fly, upon the next request [all models are executed at every request and thus those changes will take effect then if migrate = True].
This fact can lead to an interesting stuff, such as that you can make a const that holds the value of the migrate variable and set it to True while development and return it to False when you’re ready to publish your work.
db().select(db.table_name.field, orderby='<random>') You can get a random order every time the query is initiated.</li> <li> db._lastsql -> returns the last sql code generated by DAL
myquery=(db.table.field==value)|(db.table.id>10)
Warning Warning Warning :
Always use when ever doing queries the operators ‘&’, ‘|’ , Don’t use ‘and’, ‘or’ .
.delete(), .update(), .insert() and .select()
they all have a :
._delete(), ._update(), ._indert(), ._select()
that instead of performing the operation return the SQL that does.
db.define_table('rating', Field('table_name'), Field('record_id', 'integer'), Field('rate', 'integer')) db.rating.table_name.requires = IS_IN_SET(db.tables())
and whenever trying to insert some record you can do something like:
db.rating.insert(table_name = str(db.game), record_id=..., rate=...)
DAL supports ‘NOT’ using the ‘~’, so you can do something like:
db( ~db.table.field.belongs((1,2,3))).select()
charset = m.group('charset') or 'utf8' self._pool_connection(lambda : MySQLdb.Connection( db=db, user=user, passwd=passwd, host=host, port=int(port), charset=charset, )) ......................................... ......................................... # table should use this utf-8 when creating it if self._db._dbname == 'mysql': fields.append('PRIMARY KEY(%s)' % self.fields[0]) other = ' ENGINE=InnoDB CHARACTER SET utf8;'
db(db.my_table.id>0).select() or db((db.my_table.id>0) & (db.my_table.second_field == 'value') ).select() or even easier : db(db.my_table.id>0)(db.my_table.second_field == 'value').select() so: db(a)(b)(c) is the same as db((a)&(b)&(c)) in fact the former is interpreted as taking the (c) subset of the (b) subset of the (a) subset of db.
Web2py keeps track of the migration files in a folder called database, web2py generates a random name for it and you should [if you tend set migration to True to give it a name]
migrate='table_name.table' => '%s.table'%table_name
if the database is re-factored with a name change, we wouldn’t want to lose the data from the column, just have the column name changed
So what to do?
Find the .table file for that table and set migrate= to that filename.
One should actually use migrate=”mytable.table” to give a name to the table files from the beginning create instead of sing the cryptic
names created vy web2py.
You can’t reference other tables using other fields than their id, which is a good practice and in the same time efficient (strings need to be hashed while integers don’t. )
db.define_Table('my_table', ....) db.new_table = db.my_table
There’s no sync between them, changes in one of them are not reflected in the other.
table A depends on table B table B depends on table C table C depends on table A
response.menu=[ ['item name',(request.function=='action'), URL(r=request,f='action',vars={}, args=[])], ]
as you can see you check with request.function==’action’ where ‘action’ is the name of the function called [change it to the name of the controller function that is referred to by this menu item]
Functions defined in controllers and having a space after the () and before the ‘:’ are private.
ex:
def pri_action() : # do some thing
A('Download', _href=URL(....)) instead of <a href=''>'Download'</a>
You can also have a server side highlighting using CODE helper that will display code in HTML with highlighting.
{{=CODE(\"print 'hello world'\", language='python', link=None, counter=1, styles={})}}
another example:
BR -> <br/>
P(..., cr2br=True) Will replace ``\\n`` by ``<br />`` if the `cr2br` attribute is provided. P() -> <p>
class FIELDSET(DIV): tag = 'fieldset'
The fieldset tag should just wrap whatever is in it, since most designers never use tables to format forms.
The fieldset tag helps create visible rubrics with very large forms
6 Comments | web2py zen | Tagged: "active menu", "private function", "private functions", 'python 2.4', 304, admin, api, appadmin, appengine, Array, backward, behind, belongs, bigtable, blob, cache, cgi, chdir, column, command, compatibility, compatible, context, dal, DAL(None), dal. database, database, decorator, delete, dictionary, disc, distributed, doctest, documentation, doesn't, drop, enterprise, Enum, error, escape, exec(), exist, features, formname, forms, from, function, generic, generic.html, google, hidden, HTTP, HTTPS, IF_MODIFIED_SINCE, import, inheritance, insert, insertion, integrated, interact, interactive, IO, j2ee, large, line, line terminator, linux, list, locking, macko, many, medium, memcache, module, modules, multiple, MVC, mysql, no, None, not, one, openvms, oracle, orderby, orm, os, os.chdir(), others, parameters, pdf, php, postgresql, private, problem, professionals, proxy, pylons, query, quote, quotes Edit, random, reference, referencing, relationship, reload(), rename, safe, scalability, script, secure cookies, select, self, server, session, share, sharing, shell, single, small, SQLalchemy, sqldesigner, SSH, SSL, stability, state, table, template, test, thread, ticket, to, tool, transactions, turbogear, unpickled, update, upload, utf-8, uuid, validate, vars, view, web, web2py, windows, wsgi, XML, xmlrpc, \n, \r, ~ | Permalink
Posted by web2py