Done - no change.

Is it possible that the issue is SQLite specific and I need to migrate to 
MySQL or some other db?

On Thursday, June 16, 2016 at 12:14:51 PM UTC-4, Richard wrote:
>
> Can you comment out the part of the scheduler, the db lock file may come 
> from there...
>
> On Thu, Jun 16, 2016 at 12:05 PM, Marty Jones <murtin...@gmail.com 
> <javascript:>> wrote:
>
>> Controller logic is below. Error 1 is occuring under the "dashboard" 
>> function. Errors 2/3 under the user function.
>>
>> # -*- coding: utf-8 -*-
>> # this file is released under public domain and you can use without 
>> limitations
>>
>>
>> ###############################################################################
>> ## Launch with all settings via "sudo python run_server.py"
>>
>> ###############################################################################
>>
>> import operator # needed for manager_status variable
>>
>> response.title = 'nolabills'
>>
>> def jspage():
>>     link = URL('static', 'main.js')
>>     return dict(link=link)
>>
>> def index():
>>     """
>>     For registered users, redirects to the requests page
>>     For unregistered users, displays intro message
>>     """
>>     
>>     signup = URL(a=request.application, c='default', f='user/register')
>>     
>>     return dict(is_logged_in=auth.is_logged_in(), signup=signup)
>>
>> @auth.requires_membership('manager')
>> def manage():
>>     """
>>     This page, accessible by only managers, shows the current employees
>>     of a company as well as any users who are registering themselves as
>>     employees of the company.
>>     From this page a manager can approve a pending user's membership,
>>     as well as revoke the membership of a user on the current employee 
>> list.
>>     """
>>     pending_list = []
>>     approved_list = []
>>     if request.post_vars:
>>         for each in request.post_vars:
>>             key = request.post_vars.keys()[0]
>>             underscore = key.find('_')
>>             id = key[0:underscore]
>>             change = key[underscore+1:len(key)]
>>             change = None if change == "approve" else "unapproved"
>>             # modify db accordingly
>>             record = db(db.auth_user.id==id).select().first()
>>             record.registration_key=change
>>             record.update_record()
>>
>>     for row in db().select():
>>     #for row in db(db.auth_user.company==auth.user.company).select():
>>         if row.registration_key: # if pending approval by manager
>>             
>> pending_list.append({row.id:{"first":row.first_name,"last":row.last_name}})
>>         else:
>>             manager_status = auth.has_membership('manager', row.id)
>>             
>> approved_list.append({row.id:{"first":row.first_name,"last":row.last_name,"manager_status":manager_status}})
>>     return dict(pending_list=pending_list, approved_list=approved_list)
>>
>> @auth.requires_login()
>> def dashboard():
>>     """
>>     This page allows a user to send an email to
>>     a potential customer, requesting access to bill data
>>     """
>>     i = 0
>>     already_submitted = False # default is false; can only be changed if 
>> request.post_vars == True
>>     
>>     # SQLFORM version
>>     data_requests = 
>> SQLFORM.grid(db(db.data_requests.company==auth.user.company),
>>                                  fields=[db.data_requests.last_name, \
>>                                          db.data_requests.first_name, \
>>                                          db.data_requests.email, \
>>                                          db.data_requests.status, \
>>                                          db.data_requests.bill_1,
>>                                          ],
>>                                  headers={'data_requests.bill_1':'Most 
>> Recent Bill'},
>>                                  sortable=False,
>>                                  create=False,
>>                                  editable=False,
>>                                  deletable=True,
>>                                  details=False,
>>                                  maxtextlength=30,
>>                                  csv=False,
>>                                  upload=URL('download'),
>>                                  )
>>
>>     pending_list = db().select(db.data_requests.email)
>>     # if a new request has been made, update the database
>>     if request.post_vars:
>>         
>>         while not already_submitted and i <= len(data_requests):
>>             already_submitted = [True for row in pending_list if 
>> row.email == request.post_vars.email]
>>             i += 1
>>         
>>         from entergy_scraper import download
>>         from mailer import send_request
>>         
>>         if not already_submitted:
>>             # generate token
>>             import random, base64, sha
>>             token = 
>> base64.b64encode(sha.sha(str(random.random())).hexdigest())[:8]
>>             db.tokens.insert(token = token,
>>                              first_name = request.post_vars.first_name,
>>                              last_name = request.post_vars.last_name,
>>                              email = request.post_vars.email,
>>                              company = auth.user.company,
>>                              )
>>             
>>             # send request to user
>>             db.scheduler_task.insert(status = 'QUEUED',
>>                                      application_name = 
>> request.application+'/default',
>>                                      task_name = 'request',
>>                                      group_name = 'email',
>>                                      function_name = 'send_request',
>>                                      args = '["{0}", "{1}", "{2}", 
>> "{3}"]'.format( \
>>                                          request.post_vars.first, 
>> request.post_vars.last, request.post_vars.email, token),
>>                                      vars = '{}',
>>                                      enabled = True,
>>                                      start_time = request.now,
>>                                      timeout = 500, # should take less 
>> than 500 secs
>>                                      )
>>             # update data_requests to show that the task is 
>> AWAITING_CUSTOMER
>>             db.data_requests.insert(first_name = 
>> request.post_vars.first_name,
>>                                     last_name = 
>> request.post_vars.last_name,
>>                                     email = request.post_vars.email,
>>                                     company = auth.user.company,
>>                                     status = 'AWAITING_CUSTOMER',
>>                                     )
>>
>>
>>     return dict(already_submitted=already_submitted, 
>> data_requests=data_requests, pending_list=pending_list)
>>
>> def approve_request():
>>     """
>>     Allows a customer to approve a data request
>>     """
>>     submitted = 'submitted'
>>     valid_token = 'valid_token'
>>     invalid_token = 'invalid_token'
>>     
>>     
>>     # if the user has submitted their data and it's not already in the 
>> database, let them know we'll get their data
>>     if request.post_vars:
>>         status = submitted
>>         
>>         token_submitted = True if db(db.data_requests.email == 
>> request.post_vars.email).select(db.tokens.submitted).first() else False
>>         
>>         if token_submitted == False:
>>         # download data
>>             db.data_requests.insert(first_name = 
>> request.post_vars.first_name,
>>                                     last_name = 
>> request.post_vars.last_name,
>>                                     email = request.post_vars.email,
>>                                     company = auth.user.company,
>>                                     energy_username = 
>> request.post_vars.energy_username,
>>                                     energy_password = 
>> request.post_vars.energy_password,
>>                                     )
>>     
>>     # if no submission of info, try to give them the option to do so
>>     else:
>>         try:
>>             status = valid_token
>>             token = request.get_vars.token
>>             token_row = db(db.tokens.token == token).select().first()
>>             first_name = token_row.first_name
>>             last_name = token_row.last_name
>>             email = token_row.email
>>         except:
>>             status = invalid_token
>>
>>     if status == submitted or status == invalid_token:
>>         return dict(status=status, submitted=submitted, 
>> invalid_token=invalid_token, token_submitted=token_submitted)
>>     else:
>>         return dict(status=status, first_name=first_name, 
>> last_name=last_name, email=email, submitted=False, invalid_token=False, 
>> token_submitted=False)
>>     
>> def user():
>>     """
>>     exposes:
>>     http://..../[app]/default/user/login
>>     http://..../[app]/default/user/logout
>>     http://..../[app]/default/user/register
>>     http://..../[app]/default/user/profile
>>     http://..../[app]/default/user/retrieve_password
>>     http://..../[app]/default/user/change_password
>>     http://..../[app]/default/user/bulk_register
>>     use @auth.requires_login()
>>         @auth.requires_membership('group name')
>>         @auth.requires_permission('read','table name',record_id)
>>     to decorate functions that need access control
>>     also notice there is http://..../[app]/appadmin/manage/auth to allow 
>> administrator to manage users
>>     """
>>     return dict(form=auth())
>>
>> @cache.action()
>> def download():
>>     """
>>     allows downloading of uploaded files
>>     http://..../[app]/default/download/[filename]
>>     """
>>     return response.download(request, db)
>>
>> def call():
>>     """
>>     exposes services. for example:
>>     http://..../[app]/default/call/jsonrpc
>>     decorate with @services.jsonrpc the functions to expose
>>     supports xml, json, xmlrpc, jsonrpc, amfrpc, rss, csv
>>     """
>>     return service()
>>
>>
>>
>> On Thursday, June 16, 2016 at 9:36:18 AM UTC-4, Marty Jones wrote:
>>>
>>> I uploaded a local application to my DigitalOcean droplet and have been 
>>> having a nightmare of a time with the databases. I get this variety of 
>>> errors on various pages:
>>>
>>> *Error 1:*
>>>
>>> Traceback (most recent call last):
>>>   File "/home/murtyjones/app/gluon/restricted.py", line 227, in restricted
>>>     exec ccode in environment
>>>   File "/home/murtyjones/app/applications/nolabills/controllers/default.py" 
>>> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>,
>>>  line 230, in <module>
>>>   File "/home/murtyjones/app/gluon/globals.py", line 417, in <lambda>
>>>     self._caller = lambda f: f()
>>>   File "/home/murtyjones/app/gluon/tools.py", line 4241, in f
>>>     return action(*a, **b)
>>>   File "/home/murtyjones/app/applications/nolabills/controllers/default.py" 
>>> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>,
>>>  line 73, in dashboard
>>>     data_requests = 
>>> SQLFORM.grid(db(db.data_requests.company==auth.user.company),
>>>   File "/home/murtyjones/app/gluon/packages/dal/pydal/objects.py", line 91, 
>>> in __getattr__
>>>     raise AttributeError
>>> AttributeError
>>>
>>>
>>> *Error 2 (trying to apply changes as a user to own profile):*
>>>
>>> Traceback (most recent call last):
>>>   File "/home/murtyjones/app/gluon/restricted.py", line 227, in restricted
>>>     exec ccode in environment
>>>   File "/home/murtyjones/app/applications/nolabills/controllers/default.py" 
>>> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>,
>>>  line 230, in <module>
>>>   File "/home/murtyjones/app/gluon/globals.py", line 417, in <lambda>
>>>     self._caller = lambda f: f()
>>>   File "/home/murtyjones/app/applications/nolabills/controllers/default.py" 
>>> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>,
>>>  line 211, in user
>>>     return dict(form=auth())
>>>   File "/home/murtyjones/app/gluon/tools.py", line 1941, in __call__
>>>     return getattr(self, args[0])()
>>>   File "/home/murtyjones/app/gluon/tools.py", line 4026, in profile
>>>     hideerror=self.settings.hideerror):
>>>   File "/home/murtyjones/app/gluon/sqlhtml.py", line 1744, in accepts
>>>     self.id_field_name]).update(**fields)
>>>   File "/home/murtyjones/app/gluon/packages/dal/pydal/objects.py", line 
>>> 2041, in update
>>>     ret = db._adapter.update("%s" % table._tablename, self.query, fields)
>>>   File "/home/murtyjones/app/gluon/packages/dal/pydal/adapters/base.py", 
>>> line 519, in update
>>>     raise e
>>> OperationalError: attempt to write a readonly database
>>>
>>>
>>> *Error 3 (trying to logout as a user):*
>>>
>>> Traceback (most recent call last):
>>>   File "/home/murtyjones/app/gluon/restricted.py", line 227, in restricted
>>>     exec ccode in environment
>>>   File "/home/murtyjones/app/applications/nolabills/controllers/default.py" 
>>> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>,
>>>  line 230, in <module>
>>>   File "/home/murtyjones/app/gluon/globals.py", line 417, in <lambda>
>>>     self._caller = lambda f: f()
>>>   File "/home/murtyjones/app/applications/nolabills/controllers/default.py" 
>>> <https://nolabills.com/admin/default/edit/nolabills/controllers/default.py>,
>>>  line 211, in user
>>>     return dict(form=auth())
>>>   File "/home/murtyjones/app/gluon/tools.py", line 1941, in __call__
>>>     return getattr(self, args[0])()
>>>   File "/home/murtyjones/app/gluon/tools.py", line 3235, in logout
>>>     self.log_event(log, self.user)
>>>   File "/home/murtyjones/app/gluon/tools.py", line 2530, in log_event
>>>     self.table_event().insert(description=str(description % vars), 
>>> origin=origin, user_id=user_id)
>>>   File "/home/murtyjones/app/gluon/packages/dal/pydal/objects.py", line 
>>> 740, in insert
>>>     ret = self._db._adapter.insert(self, self._listify(fields))
>>>   File "/home/murtyjones/app/gluon/packages/dal/pydal/adapters/base.py", 
>>> line 482, in insert
>>>     raise e
>>> IntegrityError: FOREIGN KEY constraint failed
>>>
>>>
>>> *db.py*
>>> ## app configuration made easy. Look inside private/appconfig.ini
>>> from gluon.contrib.appconfig import AppConfig
>>> ## import current for current.db = db line
>>> from gluon import current
>>>
>>> ## once in production, remove reload=True to gain full speed
>>> myconf = AppConfig(reload=True)
>>>
>>> ## if NOT running on Google App Engine use SQLite or other DB
>>> db = DAL(myconf.take('db.uri'), pool_size=myconf.take('db.pool_size', 
>>> cast=int), migrate_enabled = myconf.get('db.migrate'), 
>>> check_reserved=['all'])
>>>
>>> ## define current.db for module usage
>>> current.db = db
>>>
>>> ## by default give a view/generic.extension to all actions from localhost
>>> ## none otherwise. a pattern can be 'controller/function.extension'
>>> response.generic_patterns = ['*'] if request.is_local else []
>>> ## choose a style for forms
>>> response.formstyle = myconf.take('forms.formstyle')  # or 
>>> 'bootstrap3_stacked' or 'bootstrap2' or other
>>> response.form_label_separator = myconf.take('forms.separator')
>>>
>>> from gluon.tools import Auth, Service, PluginManager
>>>
>>> auth = Auth(db)
>>> service = Service()
>>> plugins = PluginManager()
>>>
>>> auth.settings.extra_fields['auth_user']= [
>>>   Field('company'),
>>>   ]
>>>                     
>>> ## create all tables needed by auth if not custom tables
>>> auth.define_tables(username=False, signature=False, migrate=True, 
>>> fake_migrate=True)
>>>
>>> ## configure email
>>> mail = auth.settings.mailer
>>> mail.settings.server = 'smtp.gmail.com'
>>> mail.settings.sender = 'em...@gmail.com <javascript:>'
>>> mail.settings.login = 'em...@gmail.com:password'
>>>
>>> ## configure auth policy
>>> auth.settings.registration_requires_verification = True
>>> auth.settings.registration_requires_approval = True
>>> auth.settings.reset_password_requires_verification = True
>>>
>>> ## after defining tables, uncomment below to enable auditing
>>> # auth.enable_record_versioning(db)
>>>
>>>
>>> ## create list of companies for which this is available
>>> db.define_table('company_info',
>>>                 Field('name'),
>>>                 Field('street_address'),
>>>                 )
>>>
>>> ## create a table for the queue of not yet fulfilled data requests
>>> db.define_table('data_requests',
>>>                 Field('first_name'),
>>>                 Field('last_name'),
>>>                 Field('entergy_username'),
>>>                 Field('entergy_password'),
>>>                 Field('email'),
>>>                 Field('company'),
>>>                 Field('status', default='QUEUED'),
>>>                 Field('runs', 'integer', default=0),
>>>                 Field('bill_1', 'upload', uploadfield='bill_1_file'),
>>>                 Field('bill_1_file', 'blob'),
>>>                 )
>>>
>>>
>>> ## create a table for generating tokens
>>> db.define_table('tokens',
>>>                 Field('first_name'),
>>>                 Field('last_name'),
>>>                 Field('email'),
>>>                 Field('company'),
>>>                 Field('token'),
>>>                 Field('submitted', default=False),
>>>                 )
>>>
>>>
>>>
>>> *sql.log*
>>> timestamp: 2016-06-15T14:20:52.811948
>>> CREATE TABLE auth_user(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     first_name CHAR(128),
>>>     last_name CHAR(128),
>>>     email CHAR(512),
>>>     password CHAR(512),
>>>     registration_key CHAR(512),
>>>     reset_password_key CHAR(512),
>>>     registration_id CHAR(512)
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:20:52.856816
>>> CREATE TABLE auth_group(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     role CHAR(512),
>>>     description TEXT
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:20:52.899975
>>> CREATE TABLE auth_membership(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     user_id INTEGER REFERENCES auth_user (id) ON DELETE CASCADE  ,
>>>     group_id INTEGER REFERENCES auth_group (id) ON DELETE CASCADE  
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:20:53.040386
>>> CREATE TABLE auth_permission(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     group_id INTEGER REFERENCES auth_group (id) ON DELETE CASCADE  ,
>>>     name CHAR(512),
>>>     table_name CHAR(512),
>>>     record_id INTEGER
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:20:53.092848
>>> CREATE TABLE auth_event(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     time_stamp TIMESTAMP,
>>>     client_ip CHAR(512),
>>>     user_id INTEGER REFERENCES auth_user (id) ON DELETE CASCADE  ,
>>>     origin CHAR(512),
>>>     description TEXT
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:20:53.223004
>>> CREATE TABLE auth_cas(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     user_id INTEGER REFERENCES auth_user (id) ON DELETE CASCADE  ,
>>>     created_on TIMESTAMP,
>>>     service CHAR(512),
>>>     ticket CHAR(512),
>>>     renew CHAR(1)
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:22:53.166163
>>> ALTER TABLE auth_user ADD company CHAR(512);
>>> success!
>>> timestamp: 2016-06-15T14:22:53.554653
>>> CREATE TABLE company_info(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     name CHAR(512),
>>>     street_address CHAR(512)
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:22:53.604055
>>> CREATE TABLE data_requests(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     first_name CHAR(512),
>>>     last_name CHAR(512),
>>>     entergy_username CHAR(512),
>>>     entergy_password CHAR(512),
>>>     email CHAR(512),
>>>     company CHAR(512),
>>>     status CHAR(512),
>>>     runs INTEGER,
>>>     bill_1 CHAR(512),
>>>     bill_1_file BLOB
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:22:53.645905
>>> CREATE TABLE tokens(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     first_name CHAR(512),
>>>     last_name CHAR(512),
>>>     email CHAR(512),
>>>     company CHAR(512),
>>>     token CHAR(512),
>>>     submitted CHAR(512)
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:22:56.435830
>>> CREATE TABLE scheduler_task(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     application_name CHAR(512),
>>>     task_name CHAR(512),
>>>     group_name CHAR(512),
>>>     status CHAR(512),
>>>     function_name CHAR(512),
>>>     uuid CHAR(255) UNIQUE,
>>>     args TEXT,
>>>     vars TEXT,
>>>     enabled CHAR(1),
>>>     start_time TIMESTAMP,
>>>     next_run_time TIMESTAMP,
>>>     stop_time TIMESTAMP,
>>>     repeats INTEGER,
>>>     retry_failed INTEGER,
>>>     period INTEGER,
>>>     prevent_drift CHAR(1),
>>>     timeout INTEGER,
>>>     sync_output INTEGER,
>>>     times_run INTEGER,
>>>     times_failed INTEGER,
>>>     last_run_time TIMESTAMP,
>>>     assigned_worker_name CHAR(512)
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:22:56.501649
>>> CREATE TABLE scheduler_run(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     task_id INTEGER REFERENCES scheduler_task (id) ON DELETE CASCADE  ,
>>>     status CHAR(512),
>>>     start_time TIMESTAMP,
>>>     stop_time TIMESTAMP,
>>>     run_output TEXT,
>>>     run_result TEXT,
>>>     traceback TEXT,
>>>     worker_name CHAR(512)
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:22:56.546304
>>> CREATE TABLE scheduler_worker(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     worker_name CHAR(255) UNIQUE,
>>>     first_heartbeat TIMESTAMP,
>>>     last_heartbeat TIMESTAMP,
>>>     status CHAR(512),
>>>     is_ticker CHAR(1),
>>>     group_names TEXT,
>>>     worker_stats TEXT
>>> );
>>> success!
>>> timestamp: 2016-06-15T14:22:56.589493
>>> CREATE TABLE scheduler_task_deps(
>>>     id INTEGER PRIMARY KEY AUTOINCREMENT,
>>>     job_name CHAR(512),
>>>     task_parent INTEGER,
>>>     task_child INTEGER REFERENCES scheduler_task (id) ON DELETE CASCADE 
>>>  ,
>>>     can_visit CHAR(1)
>>> );
>>> success!
>>>
>>> No idea where to even start with this and would appreciate help.
>>>
>>> -- 
>> Resources:
>> - http://web2py.com
>> - http://web2py.com/book (Documentation)
>> - http://github.com/web2py/web2py (Source code)
>> - https://code.google.com/p/web2py/issues/list (Report Issues)
>> --- 
>> 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 <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
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/d/optout.

Reply via email to