Single row config table

87 views
Skip to first unread message

Michael Ellis

unread,
Oct 10, 2022, 2:08:56 PM10/10/22
to py4web
Most applications have parameters that are statically configured for each installation.

It's nice to keep such values in a one-row table with a primary key that doesn't auto-increment. For example, the following works nicely (at least in SQLite3) to prevent extra rows from being inserted.

id INTEGER PRIMARY KEY CHECK (id=1)

As far as I can tell, py4web (like web2py) doesn't support this explicitly. It insists on defining for every table

id INTEGER PRIMARY KEY AUTOINCREMENT

Is there any way, in py4web, to support having a config table without auto increment?

Thanks!


Jim Steil

unread,
Oct 10, 2022, 4:47:41 PM10/10/22
to py4web
You always have the option to build the table outside of py4web and set migrate=False for that table, or do fake_migrate=True.

Alternatively, py4web supports settings files that you can set per installation.  If you look at the _scaffold app you will see in settings.py that at the end it imports settings_private.py which is where I keep all of my installation-specific settings.  I keep my db config as well as all of my other installation-specify setup parameters in that file.

-Jim

Michael Ellis

unread,
Oct 16, 2022, 2:36:52 PM10/16/22
to py4web
Thanks, Jim.  After thinking it through I've settled on the following approach:

### Define the config table.
db.define_table('config',
    Field('parmA','integer', default=0),
    Field('parmB','string', default=''),
    # etc.
)
db.commit()

# Initialize the only allowed row with default values.
if db(db.config).isempty():
    db.config.insert()
    db.commit()

# Forbid further inserts, making this a one row table (at least as far as pyDAL
# is concerned). Attempts to insert will raise an exception and create a ticket in
# py4web.
def no_insert_callback():
    raise Exception("config is a one row table: attempt to insert aborted")

db.config._before_insert.append(no_insert_callback)

It's not as satisfying as having the check done in the db,  but it does what I need.

Alexander Beskopilny

unread,
Oct 17, 2022, 6:04:28 AM10/17/22
to py4web
if I'm not mistaken,
this is how it can work

def allow_id_1(f):
         if db(db.config).isempty():
             return None # False
         else:
             return True
             # raise Exception("config is a one row,  aborted")

db.config._before_insert.append( allow_id_1 )

Michael Ellis

unread,
Oct 17, 2022, 11:10:01 AM10/17/22
to Alexander Beskopilny, py4web
Thanks, Alexander. That's shorter and cleaner than my version.  OTOH, my application has external processes that access the db (read-only) so I need to make sure the config table row exists and has well-defined defaults until the system owner gets around to completing the configuration.

Cheers,
Mike

“I want you to act as if the house was on fire. Because it is.” — Greta Thunberg


--
You received this message because you are subscribed to a topic in the Google Groups "py4web" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/py4web/DZLzXscW3yQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to py4web+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/py4web/76b6a867-7f32-472e-97ae-b139c6fd392bn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages