Mapping Column Types onto Web Page Elements Adding Elements to ENUM or SET Column Definitions

But what if t he user leaves a field em pt y? I f t he field corresponds t o, say, a CHAR colum n in t he t able, do you set t he colum n value t o NULL or t o t he em pt y st ring? This t oo is a quest ion t hat can be answered by checking t he t ables st ruct ure. Det erm ine whet her or not t he colum n can cont ain NULL values. I f it can, set t he colum n t o NULL ; ot herwise, set it t o t he em pt y st ring.

9.9.6 Mapping Column Types onto Web Page Elements

Som e colum n t ypes such as ENUM and SET correspond nat urally t o elem ent s of web form s: • An ENUM has a fixed set of values from which you choose a single value. This is analogous t o a group of radio but t ons, a pop- up m enu, or a single-pick scrolling list . • A SET colum n is sim ilar, except t hat you can select m ult iple values; t his corresponds t o a group of checkboxes or a m ult iple-pick scrolling list . I f you access t he inform at ion for t hese t ypes of colum ns using SHOW COLUMNS , you can easily det erm ine t he legal values for a colum n and m ap t hem ont o t he appropriat e form elem ent aut om at ically. This allows you t o present users wit h a list of applicable values from which select ions can be m ade easily wit hout any t yping. Earlier in t his chapt er we saw how t o get ENUM and SET colum n m et adat a. The m et hods developed t here are used in Chapt er 18 , which discusses form generat ion in m ore det ail.

9.9.7 Adding Elements to ENUM or SET Column Definitions

I t s really a pain t o add a new elem ent t o an ENUM or SET colum n definit ion w hen you use ALTER TABLE , because you have t o list not only t he new elem ent , but all t he exist ing elem ent s as well. One approach for doing t his using m ysqldum p and an edit or is described in Recipe 8.3 . Anot her way t o accom plish t his t ask is t o writ e your own program t hat does m ost of t he work for you by using colum n m et adat a. Let s develop a Pyt hon script add_elem ent .py t hat generat es t he appropriat e ALTER TABLE st at em ent aut om at ically when given a t able nam e, an ENUM or SET colum n nam e, and t he new elem ent value. Suppose you want t o add hot pink t o t he colors colum n of t he item t able. The current st ruct ure of t he colum n looks like t his: mysql SHOW COLUMNS FROM item LIKE colors\G 1. row Field: colors Type: setchartreuse,mauve,lime green,puce Null: YES Key: Default: puce Extra: add_elem ent .py will use t hat inform at ion t o figure out t he correct ALTER TABLE st at em ent and w r it e it out : .add_element.py item colors hot pink ALTER TABLE item MODIFY colors setchartreuse,mauve,lime green,puce,hot pink NULL DEFAULT puce; By having add_elem ent .py produce t he st at em ent as it s out put , you have t he choice of shoving it int o m ysql for im m ediat e execut ion or saving t he out put int o a file: .add_element.py item colors hot pink | mysql cookbook .add_element.py item colors hot pink stmt.sql You m ight choose t he lat t er course if you want t he new elem ent som ewhere ot her t han at t he end of t he list of values, which is where add_elem ent .py will put it . I n t his case, edit st m t .sql t o place t he elem ent where you want it , t hen execut e t he st at em ent : vi stmt.sql mysql cookbook stmt.sql The first part of t he add_elem ent .py script im port s t he requisit e m odules and checks t he com m and- line argum ent s. This is fairly st raight forward: usrbinpython add_element.py - show ALTER TABLE statement for ENUM or SET column assumes cookbook database import sys sys.path.insert 0, usrlocalapachelibpython import re import MySQLdb import Cookbook if len sys.argv = 4: print Usage: add_element.py tbl_name col_name new_element sys.exit 1 tbl_name = sys.argv[1] col_name = sys.argv[2] elt_val = sys.argv[3] Aft er connect ing t o t he MySQL server code not shown , we need t o run a SHOW COLUMNS query t o ret rieve inform at ion about t he designat ed colum n. The following code does t his, checking t o m ake sure t hat t he colum n really exist s in t he t able: cursor = conn.cursor escape SQL pattern characters in column name to match it literally esc_col_name = re.sub r[_], r\\\1, col_name this is not a use of placeholders cursor.execute SHOW COLUMNS FROM s LIKE s tbl_name, esc_col_name info = cursor.fetchone cursor.close if info == None: print Could not retrieve information for table s, column s \ tbl_name, col_name sys.exit 1 At t his point , if t he SHOW COLUMNS st at em ent succeeded, t he inform at ion produced by it is available as a t uple st ored in t he info variable. Well need t o use several elem ent s from t his t uple. The m ost im port ant is t he colum n t ype value, which provides t he enum... or set... st ring cont aining t he colum ns current definit ion. We can use t his t o verify t hat t he colum n really is an ENUM or SET , t hen add t he new elem ent t o t he st ring j ust before t he closing parent hesis. For t he colors colum n, we want t o change t his: setchartreuse,mauve,lime green,puce To t his: setchartreuse,mauve,lime green,puce,hot pink I t s also necessary t o check whet her colum n values can be NULL and what t he default value is so t hat t he program can add t he appropriat e inform at ion t o t he ALTER TABLE st at em ent . The code t hat does all t his is as follows: get column type string; make sure it begins with ENUM or SET type = info[1] if not re.match enum|set, type: print table s, column s is not an ENUM or SET tbl_name, col_name sys.exit1 add quotes, insert comma and new element just before closing paren elt_val = conn.literal elt_val type = re.sub \, , + elt_val + , type determine whether column can contain NULL values if info[2] == YES: nullable = NULL else: nullable = NOT NULL; construct DEFAULT clause add surrounding quotes unless value is NULL default = DEFAULT + conn.literal info[4] print ALTER TABLE s\n\tMODIFY s\n\ts\n\ts s; \ tbl_name, col_name, type, nullable, default That s it . You now have a working ENUM - or SET -alt ering program . St ill, add_elem ent .py is fairly basic and could be im proved in various ways: • Make sure t hat t he elem ent value youre adding t o t he colum n isnt already t here. • Allow add_elem ent .py t o t ake m ore t han one argum ent aft er t he colum n nam e and add all of t hem t o t he colum n definit ion at t he sam e t im e. • Add an opt ion t o indicat e t hat t he nam ed elem ent should be delet ed rat her t han added. • Add an opt ion t hat t ells t he script t o execut e t he ALTER TABLE st at em ent im m ediat ely rat her t han displaying it . • I f you have a version of MySQL older t han 3.22.16, it wont underst and t he MODIFY col_name synt ax used by add_elem ent .py. You m ay want t o edit t he script t o use CHANGE col_name synt ax inst ead. The follow ing t w o st at em ent s are equivalent : • ALTER TABLE tbl_name MODIFY col_name col_definition ; ALTER TABLE tbl_name CHANGE col_name col_name col_definition ; add_elem ent .py uses MODIFY because it s less confusing t han CHANGE .

9.9.8 Retrieving Dates in Non-ISO Format