I am trying to implement a common login across multiple
applications.
It occurred to me that the applications needed to share the auth
tables, so I migrated from sqlite to Postgresql. The migration
appears to be working with my Purchasing application.
I pruned all the application table defs from db.py and copied it to
the welcome app.
When I try to run the welcome app I get an exception. The error
snapshot says:
<class 'psycopg2.ProgrammingError'>(relation "auth_group" already
exists
The traceback says:
Traceback (most recent call last):
File "/home/cjk/plag/gluon/restricted.py", line 192, in restricted
exec ccode in environment
File "/home/cjk/plag/applications/welcome/models/db.py", line 123,
in <module>
auth.define_tables() # creates all
needed tables
File "/home/cjk/plag/gluon/tools.py", line 1232, in define_tables
format = '%(role)s (%(id)s)'))
File "/home/cjk/plag/gluon/dal.py", line 4311, in define_table
polymodel=polymodel)
File "/home/cjk/plag/gluon/dal.py", line 642, in create_table
self.create_sequence_and_triggers(query,table)
File "/home/cjk/plag/gluon/dal.py", line 1720, in
create_sequence_and_triggers
self.execute(query)
File "/home/cjk/plag/gluon/dal.py", line 1262, in execute
return self.log_execute(*a, **b)
File "/home/cjk/plag/gluon/dal.py", line 1257, in log_execute
ret = self.cursor.execute(*a,**b)
ProgrammingError: relation "auth_group" already exists
db.py looks like this:
# -*- coding: utf-8 -*-
db = DAL('postgres://theuser:password@localhost:5432/mydb',
migrate=False)
# 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 []
from gluon.tools import Mail, Auth, Crud, Service, PluginManager,
prettydate
mail = Mail() # mailer
auth = Auth(db) # authentication/
authorization
crud = Crud(db) # for CRUD helpers
using auth
service = Service() # for json, xml,
jsonrpc, xmlrpc, amfrpc
plugins = PluginManager() # for configuring
plugins
mail.settings.server = 'logging' or 'smtp.gmail.com:587' # your SMTP
server
mail.settings.sender = '[email protected]' # your email
mail.settings.login = 'None' # your credentials or None
auth.settings.hmac_key = 'sha512:6db047cf-363a-4d4e-b697-
c229c6ef8752' # before define_tables()
db.define_table('tenants',
Field('name', length=64, default=''),
migrate=False)
db.define_table(
'auth_user',
Field('first_name', length=128, default='', label='First name',
required=True, comment=SPAN('Required',
_style='color:orange;')),
Field('middle_name', length=128, default='', label='Middle
name'),
Field('last_name', length=128, default='', label='Last name'),
Field('generation', length=16, default='', label='Generation'),
Field('address', length=128, default=''),
Field('address_2', length=128, default=''),
Field('city', length=32, default=''),
Field('state', length=32, default=''),
Field('zip', length=12, default=''),
Field('email', length=128, default='', unique=True),
Field('password', 'password', length=512,
writable=False, readable=False, label='Password'),
Field('registration_key', length=512,
writable=False, readable=False, default=''),
Field('reset_password_key', length=512,
writable=False, readable=False, default=''),
Field('registration_id', length=512,
writable=False, readable=False, default=''),
Field('land_line', length=32, default=''),
Field('mobile', length=32, default=''),
Field('fax', length=32, default=''),
Field('is_staff', 'boolean', default=False),
Field('is_trainer', 'boolean', default=False),
Field('created_on', 'datetime', default=request.now),
Field('created_by', 'integer'),
Field('updated_on', 'datetime', default=request.now),
Field('updated_by', 'integer'),
Field('is_active', 'boolean', default=True),
Field('tenant_link', db.tenants),
## Field('request_tenant', 'integer'),
format='%(first_name)s %(middle_name)s %(last_name)s %
(generation)s',
migrate=False
)
db.auth_user.first_name.requires = \
IS_NOT_EMPTY(error_message='First name is required')
db.auth_user.last_name.requires = \
IS_NOT_EMPTY(error_message='Last name is required')
db.auth_user.password.requires = [IS_STRONG(), CRYPT()]
db.auth_user.email.requires = [IS_EMPTY_OR(
[IS_EMAIL(error_message=auth.messages.invalid_email),
IS_NOT_IN_DB(db, 'auth_user.email')])]
db.auth_user.tenant_link.requires = IS_IN_DB(db, 'tenants.id',
'%(name)s',
zero= "Choose")
db.auth_user.is_active.readable = db.auth_user.is_active.writable =
False
db.auth_user.created_on.readable = db.auth_user.created_on.writable =
False
db.auth_user.created_by.readable = db.auth_user.created_by.writable =
False
db.auth_user.updated_on.readable = db.auth_user.updated_on.writable =
False
db.auth_user.updated_by.readable = db.auth_user.updated_by.writable =
False
db.auth_user.tenant_link.readable =
db.auth_user.tenant_link.writable = False
signature = db.Table(
db, 'signature',
Field(
'created_on', 'datetime', default=request.now,
readable=False, writable=False),
Field('created_by', db.auth_user, default=auth.user_id,
readable=False, writable=False),
Field('updated_on', 'datetime', update=request.now,
readable=False, writable=False),
Field('updated_by', db.auth_user, update=auth.user_id,
readable=False, writable=False),
Field('is_active', 'boolean', default=True,
readable=False, writable=False)
)
auth.define_tables() # creates all needed
tables
auth.settings.reset_password_requires_verification = True
auth.messages.reset_password = 'Click on the link
http://'+request.env.http_host+URL('default','user',args=['reset_password'])+'/%(key)s
to reset your password'
crud.settings.auth = auth # =auth to enforce authorization on
crud
db.define_table('tenant_groups',
Field('tenant_id', db.tenants),
Field('group_id', db.auth_group),
Field('is_default', 'boolean', default=False),
migrate=False
)
db.tenant_groups.tenant_id.requires = IS_IN_DB(db, db.tenants.id,
'%(name)s',
zero = 'Choose a
tenant')
db.tenant_groups.group_id.requires = IS_IN_DB(db, db.auth_group.id,
'%(role)',
zero = 'Chose a group')
db.auth_permission.table_name.requires = IS_IN_SET(db.tables)