Package turbogears :: Package command :: Module sacommand
[hide private]

Source Code for Module turbogears.command.sacommand

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