Package turbogears :: Package command :: Module sacommand

Source Code for Module turbogears.command.sacommand

  1  from peak.rules import abstract, when, around 
  2  from turbogears import config 
  3  from turbogears.util import get_model 
  4  try: 
  5      from sqlalchemy import MetaData, exceptions, Table, String, Unicode 
  6      from turbogears.database import bind_metadata, metadata, get_engine 
  7  except ImportError: # if not available, complain only at run-time 
  8      from turbogears.util import missing_dependency_error 
  9      no_sqlalchemy = missing_dependency_error('SQLAlchemy') 
 10  else: 
 11      from sqlalchemy import Text, UnicodeText 
 12      no_sqlalchemy = False 
13 14 15 @abstract() 16 -def sacommand(command, args):
17 pass
18 19 @around(sacommand, "command and command != 'help' and no_sqlalchemy")
20 -def no_engine(command, args):
21 print no_sqlalchemy
22 23 @when(sacommand, "command == 'help'")
24 -def help(command, args):
25 print """TurboGears SQLAlchemy Helper 26 27 tg-admin sql command [options] 28 29 Available commands: 30 create Create tables 31 execute Execute SQL statements 32 help Show help 33 list List tables that appear in the model 34 status Show differences between model and database 35 """
36 37 @when(sacommand, "command == 'create'")
38 -def create(command, args):
39 print "Creating tables at %s" % (config.get('sqlalchemy.dburi')) 40 bind_metadata() 41 get_model() 42 metadata.create_all()
43 44 @when(sacommand, "command == 'list'")
45 -def list_(command, args):
46 get_model() 47 for tbl in metadata.tables.values(): 48 print tbl.fullname
49 50 @when(sacommand, "command == 'execute'")
51 -def execute(command, args):
52 eng = get_engine() 53 for cmd in args[2:]: 54 ret = eng.execute(cmd) 55 try: 56 print list(ret) 57 except: 58 # Proceed silently if the command produced no results 59 pass
60 61 @when(sacommand, "command == 'status'")
62 -def status(command, args):
63 bind_metadata() 64 get_model() 65 ret = compare_metadata(metadata, MetaData(metadata.bind)) 66 for l in ret: 67 print l 68 if not ret: 69 print "Database matches model"
70
71 -def indent(ls):
72 return [' ' + l for l in ls]
73
74 -def compare_metadata(pym, dbm):
75 rc = [] 76 for pyt in pym.tables.values(): 77 try: 78 dbt = Table(pyt.name, dbm, autoload=True, schema=pyt.schema) 79 except exceptions.NoSuchTableError: 80 rc.extend(("Create table " + pyt.fullname, '')) 81 else: 82 ret = compare_table(pyt, dbt) 83 if ret: 84 rc.append("Change table " + pyt.fullname) 85 rc.extend(indent(ret) + ['']) 86 return rc
87
88 -def compare_table(pyt, dbt):
89 rc = [] 90 dbcols = dict([(s.lower(), s) for s in dbt.columns.keys()]) 91 for pyc in pyt.columns: 92 name = pyc.name.lower() 93 if name in dbcols: 94 ret = compare_column(pyc, dbt.columns[dbcols[name]]) 95 if ret: 96 rc.append("Change column " + pyc.name) 97 rc.extend(indent(ret)) 98 dbcols.pop(name) 99 else: 100 rc.append("Add column " + pyc.name) 101 for dbcol in dbcols: 102 rc.append("Remove column " + dbcol) 103 return rc
104
105 -def compare_column(pyc, dbc):
106 rc = [] 107 pyt, dbt = pyc.type, dbc.type 108 109 # Table reflection cannot recognize Unicode, so check only for String 110 if isinstance(pyt, Unicode): 111 pyt = String(pyt.length) 112 elif isinstance(pyt, UnicodeText): 113 pyt = Text(pyt.length) 114 115 # Check type 116 if not isinstance(dbt, pyt.__class__): 117 rc.append('Change type to ' + pyt.__class__.__name__) 118 119 # Check length (for strings) 120 else: 121 if isinstance(pyt, String): 122 if pyt.length != dbt.length: 123 rc.append('Change length to ' + str(pyt.length)) 124 125 # Check primary key 126 if dbc.primary_key != pyc.primary_key: 127 rc.append(pyc.primary_key and 'Make primary key' or 'Remove primary key') 128 129 # TODO: Check foreign keys 130 131 # Check default 132 if (dbc.default is not None and pyc.default is not None 133 and dbc.default != pyc.default): 134 rc.append('Change default to ' + str(pyc.default.arg)) 135 136 # Check index 137 if dbc.index is not None and dbc.index != pyc.index: 138 rc.append(pyc.index and 'Add index' or 'Remove index') 139 140 return rc
141