Ticket #5062: NewMSSQL.diff
File NewMSSQL.diff, 38.0 KB (added by , 17 years ago) |
---|
-
contrib/sessions/middleware.py
59 59 self._session_cache = {} 60 60 else: 61 61 try: 62 datenow = datetime.datetime.now() 63 if hasattr(datenow, 'microsecond'): 64 datenow = datenow.replace(microsecond=0) 62 65 s = Session.objects.get(session_key=self.session_key, 63 expire_date__gt=date time.datetime.now())66 expire_date__gt=datenow) 64 67 self._session_cache = s.get_decoded() 65 68 except (Session.DoesNotExist, SuspiciousOperation): 66 69 self._session_cache = {} -
db/backends/mssql/base.py
1 """ 2 Alpha Multi-plataform MSSQL database backend for Django. 3 4 Requires pymssql >= v0.8.0: http://pymssql.sourceforge.net/ 5 """ 6 if __name__ == '__main__': 7 import sys 8 import os 9 10 SETTINGS_MODULE = 'settings' 11 12 project_dir = r'E:\Proyectos\Python\mysite' 13 sys.path.append(os.path.join(project_dir, '..')) 14 sys.path.append("..") 15 sys.path.pop() 16 os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' 17 18 19 import datetime 20 from django.db.backends import util 21 from django.core.exceptions import ImproperlyConfigured 22 23 try: 24 import pymssql as Database 25 except ImportError, e: 26 raise ImproperlyConfigured, "Error loading pymssql module: %s" % e 27 28 try: 29 import mx 30 except ImportError: 31 mx = None 32 33 try: 34 # Only exists in Python 2.4+ 35 from threading import local 36 except ImportError: 37 # Import copy of _thread_local.py from Python 2.4 38 from django.utils._threading_local import local 39 40 DatabaseError = Database.DatabaseError 41 IntegrityError = Database.IntegrityError 42 43 #Configure support options: 44 allows_group_by_ordinal = True 45 allows_unique_and_pk = True 46 autoindexes_primary_keys = True 47 needs_datetime_string_cast = True 48 needs_upper_for_iops = False 49 supports_constraints = True 50 supports_tablespaces = False 51 uses_case_insensitive_names = False 52 53 def complain(*args, **kwargs): 54 raise ImproperlyConfigured, "You haven't set the DATABASE_ENGINE setting yet." 55 56 def ignore(*args, **kwargs): 57 pass 58 59 class DatabaseError(Exception): 60 pass 61 62 class IntegrityError(DatabaseError): 63 pass 64 65 class DatabaseWrapper(local): 66 def __init__(self, **kwargs): 67 self.connection = None 68 self.queries = [] 69 70 def cursor(self): 71 from django.conf import settings 72 if self.connection is None: 73 if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '': 74 raise ImproperlyConfigured, "You need to specify both DATABASE_NAME and DATABASE_USER in your Django settings file." 75 if not settings.DATABASE_HOST: 76 settings.DATABASE_HOST = "127.0.0.1" 77 # TODO: Handle DATABASE_PORT. 78 self.connection = Database.connect(host=settings.DATABASE_HOST,user=settings.DATABASE_USER,password=settings.DATABASE_PASSWORD,database=settings.DATABASE_NAME) 79 80 self.connection.cursor().execute("SET DATEFORMAT ymd\nGO") 81 82 cursor = self.connection.cursor() 83 if settings.DEBUG: 84 return util.CursorDebugWrapper(cursor, self) 85 return cursor 86 87 def _commit(self): 88 if self.connection is not None: 89 return self.connection.commit() 90 91 def _rollback(self): 92 if self.connection is not None: 93 return self.connection.rollback() 94 95 def close(self): 96 if self.connection is not None: 97 self.connection.close() 98 self.connection = None 99 100 ''' 101 Return the major version of the server. 7=Sql 7,8=Sql2000,9=Sql2005 102 ''' 103 def version(): 104 cur = DatabaseWrapper().cursor() 105 cur.execute("SELECT SERVERPROPERTY('ProductVersion')") 106 107 return int(cur.fetchone()[0].split('.')[0]) 108 109 def quote_name(name): 110 if name.startswith('[') and name.endswith(']'): 111 return name # Quoting once is enough. 112 return '[%s]' % name 113 114 dictfetchone = util.dictfetchone 115 dictfetchmany = util.dictfetchmany 116 dictfetchall = util.dictfetchall 117 118 def get_last_insert_id(cursor, table_name, pk_name): 119 cursor.execute("SELECT %s FROM %s WHERE %s = IDENT_CURRENT('%s')" % (pk_name, table_name, pk_name,table_name)) 120 return cursor.fetchone()[0] 121 122 def get_date_extract_sql(lookup_type, table_name): 123 # lookup_type is 'year', 'month', 'day' 124 return "DATEPART(%s, %s)" % (lookup_type, table_name) 125 126 def get_date_trunc_sql(lookup_type, field_name): 127 # lookup_type is 'year', 'month', 'day' 128 if lookup_type=='year': 129 return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/01/01')" % field_name 130 if lookup_type=='month': 131 return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/' + Convert(varchar, DATEPART(month, %s)) + '/01')" % (field_name, field_name) 132 if lookup_type=='day': 133 return "Convert(datetime, Convert(varchar(12), %s))" % field_name 134 135 def get_datetime_cast_sql(): 136 return None 137 138 def get_limit_offset_sql(limit, offset=None): 139 # Limits and offset are too complicated to be handled here. 140 # Look for a implementation similar to oracle backend 141 return "" 142 143 def get_random_function_sql(): 144 return "RAND()" 145 146 def get_deferrable_sql(): 147 # TODO: Workaround cicle paths... 148 # DEFERRABLE and INITALLY DEFFERRED are not apparently supported on constraints 149 # This cause SQL Server message 1750, severity 16, state 0, for example in the multiple joins path of comments. 150 # So, this left Sql Server as if have not relations :( 151 #return " ON DELETE CASCADE ON UPDATE CASCADE" 152 return "" 153 154 def get_fulltext_search_sql(field_name): 155 raise NotImplementedError 156 157 def get_drop_foreignkey_sql(): 158 return "DROP CONSTRAINT" 159 160 def get_pk_default_value(): 161 return "DEFAULT" 162 163 def get_max_name_length(): 164 return None 165 166 def get_start_transaction_sql(): 167 return "BEGIN;" 168 169 def get_tablespace_sql(tablespace, inline=False): 170 return "ON %s" % quote_name(tablespace) 171 172 def get_autoinc_sql(table): 173 return None 174 175 def get_sql_flush(sql_styler, full_table_list, sequences): 176 """Return a list of SQL statements required to remove all data from 177 all tables in the database (without actually removing the tables 178 themselves) and put the database in an empty 'initial' state 179 """ 180 # Cannot use TRUNCATE on tables that are reference by a FOREIGN KEY 181 # So must use the much slower DELETE 182 sql_list = ['%s %s %s;' % \ 183 (sql_styler.SQL_KEYWORD('DELETE'), 184 sql_styler.SQL_KEYWORD('FROM'), 185 sql_styler.SQL_FIELD(quote_name(table)) 186 ) for table in full_table_list] 187 #The reset the counters on each table. 188 sql_list.extend(['%s %s %s %s %s %s %s;' % ( 189 sql_styler.SQL_KEYWORD('DBCC'), 190 sql_styler.SQL_KEYWORD('CHECKIDENT'), 191 sql_styler.SQL_FIELD(quote_name(seq["table"])), 192 sql_styler.SQL_KEYWORD('RESEED'), 193 sql_styler.SQL_FIELD('1'), 194 sql_styler.SQL_KEYWORD('WITH'), 195 sql_styler.SQL_KEYWORD('NO_INFOMSGS'), 196 ) for seq in sequences]) 197 198 return sql_list 199 200 def get_sql_sequence_reset(style, model_list): 201 "Returns a list of the SQL statements to reset sequences for the given models." 202 # No sequence reset required 203 return [] 204 205 OPERATOR_MAPPING = { 206 'exact': '= %s', 207 'iexact': 'LIKE %s', 208 'contains': 'LIKE %s', 209 'icontains': 'LIKE %s', 210 'gt': '> %s', 211 'gte': '>= %s', 212 'lt': '< %s', 213 'lte': '<= %s', 214 'startswith': 'LIKE %s', 215 'endswith': 'LIKE %s', 216 'istartswith': 'LIKE %s', 217 'iendswith': 'LIKE %s', 218 } 219 220 if __name__ == '__main__': 221 from mysite.polls.models import Poll, Choice 222 from django.contrib.auth.models import User 223 from datetime import datetime 224 Poll.objects.all() 225 p = Poll(question="What's up?", pub_date=datetime.now()) 226 p.save() 227 print p.id 228 229 db=DatabaseWrapper() 230 print version() 231 232 -
db/backends/mssql/client.py
1 def runshell(): 2 raise NotImplementedError -
db/backends/mssql/introspection.py
1 def get_table_list(cursor): 2 "Returns a list of table names in the current database." 3 cursor.execute("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'") 4 return [row[2] for row in cursor.fetchall()] 5 6 def _is_auto_field(cursor, table_name, column_name): 7 cursor.execute("SELECT COLUMNPROPERTY( OBJECT_ID('%s'),'%s','IsIdentity')" % (table_name, column_name)) 8 return cursor.fetchall()[0][0] 9 10 def get_table_description(cursor, table_name, identity_check=True): 11 """Returns a description of the table, with the DB-API cursor.description interface. 12 13 The 'auto_check' parameter has been added to the function argspec. 14 If set to True, the function will check each of the table's fields for the 15 IDENTITY property (the IDENTITY property is the MSSQL equivalent to an AutoField). 16 17 When a field is found with an IDENTITY property, it is given a custom field number 18 of -777, which maps to the 'AutoField' value in the DATA_TYPES_REVERSE dict. 19 """ 20 cursor.execute("SELECT TOP 1 * FROM %s" % table_name) 21 cursor.nextset() 22 items = [] 23 if identity_check: 24 for data in cursor.description: 25 if _is_auto_field(cursor, table_name, data[0]): 26 data = list(data) 27 data[1] = -777 28 items.append(list(data)) 29 else: 30 items = cursor.description 31 return items 32 33 def _name_to_index(cursor, table_name): 34 """ 35 Returns a dictionary of {field_name: field_index} for the given table. 36 Indexes are 0-based. 37 """ 38 return dict([(d[0], i) for i, d in enumerate(get_table_description(cursor, table_name, identity_check=False))]) 39 40 def get_relations(cursor, table_name): 41 """ 42 Returns a dictionary of {field_index: (field_index_other_table, other_table)} 43 representing all relationships to the given table. Indexes are 0-based. 44 """ 45 table_index = _name_to_index(cursor, table_name) 46 sql = """SELECT e.COLUMN_NAME AS column_name, 47 c.TABLE_NAME AS referenced_table_name, 48 d.COLUMN_NAME AS referenced_column_name 49 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS a 50 INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS b 51 ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME 52 INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE AS c 53 ON b.UNIQUE_CONSTRAINT_NAME = c.CONSTRAINT_NAME 54 INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS d 55 ON c.CONSTRAINT_NAME = d.CONSTRAINT_NAME 56 INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS e 57 ON a.CONSTRAINT_NAME = e.CONSTRAINT_NAME 58 WHERE a.TABLE_NAME = ? AND 59 a.CONSTRAINT_TYPE = 'FOREIGN KEY'""" 60 cursor = Cursor(cursor.db.connection) 61 cursor.execute(sql, (table_name,)) 62 return dict([(table_index[item[0]], (_name_to_index(cursor, item[1])[item[2]], item[1])) 63 for item in cursor.fetchall()]) 64 65 def get_indexes(cursor, table_name): 66 """ 67 Returns a dictionary of fieldname -> infodict for the given table, 68 where each infodict is in the format: 69 {'primary_key': boolean representing whether it's the primary key, 70 'unique': boolean representing whether it's a unique index} 71 """ 72 sql = """SELECT b.COLUMN_NAME, a.CONSTRAINT_TYPE 73 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS a INNER JOIN 74 INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS b 75 ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME AND 76 a.TABLE_NAME = b.TABLE_NAME 77 WHERE a.TABLE_NAME = ? AND 78 (CONSTRAINT_TYPE = 'PRIMARY KEY' OR 79 CONSTRAINT_TYPE = 'UNIQUE')""" 80 field_names = [item[0] for item in get_table_description(cursor, table_name, identity_check=False)] 81 cursor = Cursor(cursor.db.connection) 82 cursor.execute(sql, (table_name,)) 83 indexes = {} 84 results = {} 85 data = cursor.fetchall() 86 if data: 87 results.update(data) 88 for field in field_names: 89 val = results.get(field, None) 90 indexes[field] = dict(primary_key=(val=='PRIMARY KEY'), unique=(val=='UNIQUE')) 91 return indexes 92 93 # A reference for the values below: 94 # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdcstdatatypeenum.asp 95 DATA_TYPES_REVERSE = { 96 # 8192 : Array , 97 # 128 : Binary , 98 # 9 : IDispatch , 99 # 12 : Variant , 100 # 13 : IUnknown , 101 # 21 : UnsignedBigInt, 102 # 132 : UserDefined , 103 # 0 : Empty , 104 # 136 : Chapter , 105 # 138 : PropVariant , 106 # 204 : VarBinary , 107 # 205 : LongVarBinary , 108 -777: 'AutoField', # Custom number used to identify AutoFields 109 2 : 'SmallIntegerField', # SmallInt 110 3 : 'IntegerField', # Integer 111 4 : 'FloatField', # Single 112 5 : 'FloatField', # Decimal 113 6 : 'FloatField', # Currency 114 7 : 'DateField', # Date 115 8 : 'CharField', # BSTR 116 10 : 'IntegerField', # Error 117 11 : 'BooleanField', # Boolean 118 14 : 'FloatField', # Decimal 119 16 : 'SmallIntegerField', # TinyInt 120 17 : 'PositiveSmallIntegerField', # UnsignedTinyInt 121 18 : 'PositiveSmallIntegerField', # UnsignedSmallInt 122 19 : 'PositiveIntegerField', # UnsignedInt 123 20 : 'IntegerField', # BigInt 124 64 : 'DateTimeField', # FileTime 125 72 : 'CharField', # GUID 126 129 : 'CharField', # Char 127 130 : 'CharField', # WChar 128 131 : 'FloatField', # Numeric 129 133 : 'DateField', # DBDate 130 134 : 'TimeField', # DBTime 131 135 : 'DateTimeField', # DBTimeStamp 132 139 : 'FloatField', # VarNumeric 133 200 : 'CharField', # VarChar 134 201 : 'TextField', # LongVarChar 135 202 : 'CharField', # VarWChar 136 203 : 'TextField', # LongVarWChar 137 } 138 No newline at end of file -
db/backends/mssql/creation.py
1 DATA_TYPES = { 2 'AutoField': 'int IDENTITY (1, 1)', 3 'BooleanField': 'bit', 4 'CharField': 'varchar(%(maxlength)s)', 5 'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)', 6 'DateField': 'datetime', 7 'DateTimeField': 'datetime', 8 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', 9 'FileField': 'varchar(254)', 10 'FilePathField': 'varchar(254)', 11 'FloatField': 'double precision', 12 'ImageField': 'varchar(254)', 13 'IntegerField': 'int', 14 'IPAddressField': 'char(15)', 15 'ManyToManyField': None, 16 'NullBooleanField': 'bit', 17 'OneToOneField': 'int', 18 'PhoneNumberField': 'varchar(20)', 19 #The check must be unique in for the database. Put random so the regresion test not complain about duplicate names 20 'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(creation_counter)s_%(column)s] CHECK ([%(column)s] > 0)', 21 'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(creation_counter)s_%(column)s] CHECK ([%(column)s] > 0)', 22 'SlugField': 'varchar(%(maxlength)s)', 23 'SmallIntegerField': 'smallint', 24 'TextField': 'text', 25 'TimeField': 'datetime', 26 'USStateField': 'varchar(2)', 27 } -
db/backends/mssql/base.py
1 """ 2 Alpha Multi-plataform MSSQL database backend for Django. 3 4 Requires pymssql >= v0.8.0: http://pymssql.sourceforge.net/ 5 """ 6 if __name__ == '__main__': 7 import sys 8 import os 9 10 SETTINGS_MODULE = 'settings' 11 12 project_dir = r'E:\Proyectos\Python\mysite' 13 sys.path.append(os.path.join(project_dir, '..')) 14 sys.path.append("..") 15 sys.path.pop() 16 os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' 17 18 19 import datetime 20 from django.db.backends import util 21 from django.core.exceptions import ImproperlyConfigured 22 23 try: 24 import pymssql as Database 25 except ImportError, e: 26 raise ImproperlyConfigured, "Error loading pymssql module: %s" % e 27 28 try: 29 import mx 30 except ImportError: 31 mx = None 32 33 try: 34 # Only exists in Python 2.4+ 35 from threading import local 36 except ImportError: 37 # Import copy of _thread_local.py from Python 2.4 38 from django.utils._threading_local import local 39 40 DatabaseError = Database.DatabaseError 41 IntegrityError = Database.IntegrityError 42 43 #Configure support options: 44 allows_group_by_ordinal = True 45 allows_unique_and_pk = True 46 autoindexes_primary_keys = True 47 needs_datetime_string_cast = True 48 needs_upper_for_iops = False 49 supports_constraints = True 50 supports_tablespaces = False 51 uses_case_insensitive_names = False 52 53 def complain(*args, **kwargs): 54 raise ImproperlyConfigured, "You haven't set the DATABASE_ENGINE setting yet." 55 56 def ignore(*args, **kwargs): 57 pass 58 59 class DatabaseError(Exception): 60 pass 61 62 class IntegrityError(DatabaseError): 63 pass 64 65 class DatabaseWrapper(local): 66 def __init__(self, **kwargs): 67 self.connection = None 68 self.queries = [] 69 70 def cursor(self): 71 from django.conf import settings 72 if self.connection is None: 73 if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '': 74 raise ImproperlyConfigured, "You need to specify both DATABASE_NAME and DATABASE_USER in your Django settings file." 75 if not settings.DATABASE_HOST: 76 settings.DATABASE_HOST = "127.0.0.1" 77 # TODO: Handle DATABASE_PORT. 78 self.connection = Database.connect(host=settings.DATABASE_HOST,user=settings.DATABASE_USER,password=settings.DATABASE_PASSWORD,database=settings.DATABASE_NAME) 79 80 self.connection.cursor().execute("SET DATEFORMAT ymd\nGO") 81 82 cursor = self.connection.cursor() 83 if settings.DEBUG: 84 return util.CursorDebugWrapper(cursor, self) 85 return cursor 86 87 def _commit(self): 88 if self.connection is not None: 89 return self.connection.commit() 90 91 def _rollback(self): 92 if self.connection is not None: 93 return self.connection.rollback() 94 95 def close(self): 96 if self.connection is not None: 97 self.connection.close() 98 self.connection = None 99 100 ''' 101 Return the major version of the server. 7=Sql 7,8=Sql2000,9=Sql2005 102 ''' 103 def version(): 104 cur = DatabaseWrapper().cursor() 105 cur.execute("SELECT SERVERPROPERTY('ProductVersion')") 106 107 return int(cur.fetchone()[0].split('.')[0]) 108 109 def quote_name(name): 110 if name.startswith('[') and name.endswith(']'): 111 return name # Quoting once is enough. 112 return '[%s]' % name 113 114 dictfetchone = util.dictfetchone 115 dictfetchmany = util.dictfetchmany 116 dictfetchall = util.dictfetchall 117 118 def get_last_insert_id(cursor, table_name, pk_name): 119 cursor.execute("SELECT %s FROM %s WHERE %s = IDENT_CURRENT('%s')" % (pk_name, table_name, pk_name,table_name)) 120 return cursor.fetchone()[0] 121 122 def get_date_extract_sql(lookup_type, table_name): 123 # lookup_type is 'year', 'month', 'day' 124 return "DATEPART(%s, %s)" % (lookup_type, table_name) 125 126 def get_date_trunc_sql(lookup_type, field_name): 127 # lookup_type is 'year', 'month', 'day' 128 if lookup_type=='year': 129 return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/01/01')" % field_name 130 if lookup_type=='month': 131 return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/' + Convert(varchar, DATEPART(month, %s)) + '/01')" % (field_name, field_name) 132 if lookup_type=='day': 133 return "Convert(datetime, Convert(varchar(12), %s))" % field_name 134 135 def get_datetime_cast_sql(): 136 return None 137 138 def get_limit_offset_sql(limit, offset=None): 139 # Limits and offset are too complicated to be handled here. 140 # Look for a implementation similar to oracle backend 141 return "" 142 143 def get_random_function_sql(): 144 return "RAND()" 145 146 def get_deferrable_sql(): 147 # TODO: Workaround cicle paths... 148 # DEFERRABLE and INITALLY DEFFERRED are not apparently supported on constraints 149 # This cause SQL Server message 1750, severity 16, state 0, for example in the multiple joins path of comments. 150 # So, this left Sql Server as if have not relations :( 151 #return " ON DELETE CASCADE ON UPDATE CASCADE" 152 return "" 153 154 def get_fulltext_search_sql(field_name): 155 raise NotImplementedError 156 157 def get_drop_foreignkey_sql(): 158 return "DROP CONSTRAINT" 159 160 def get_pk_default_value(): 161 return "DEFAULT" 162 163 def get_max_name_length(): 164 return None 165 166 def get_start_transaction_sql(): 167 return "BEGIN;" 168 169 def get_tablespace_sql(tablespace, inline=False): 170 return "ON %s" % quote_name(tablespace) 171 172 def get_autoinc_sql(table): 173 return None 174 175 def get_sql_flush(sql_styler, full_table_list, sequences): 176 """Return a list of SQL statements required to remove all data from 177 all tables in the database (without actually removing the tables 178 themselves) and put the database in an empty 'initial' state 179 """ 180 # Cannot use TRUNCATE on tables that are reference by a FOREIGN KEY 181 # So must use the much slower DELETE 182 sql_list = ['%s %s %s;' % \ 183 (sql_styler.SQL_KEYWORD('DELETE'), 184 sql_styler.SQL_KEYWORD('FROM'), 185 sql_styler.SQL_FIELD(quote_name(table)) 186 ) for table in full_table_list] 187 #The reset the counters on each table. 188 sql_list.extend(['%s %s %s %s %s %s %s;' % ( 189 sql_styler.SQL_KEYWORD('DBCC'), 190 sql_styler.SQL_KEYWORD('CHECKIDENT'), 191 sql_styler.SQL_FIELD(quote_name(seq["table"])), 192 sql_styler.SQL_KEYWORD('RESEED'), 193 sql_styler.SQL_FIELD('1'), 194 sql_styler.SQL_KEYWORD('WITH'), 195 sql_styler.SQL_KEYWORD('NO_INFOMSGS'), 196 ) for seq in sequences]) 197 198 return sql_list 199 200 def get_sql_sequence_reset(style, model_list): 201 "Returns a list of the SQL statements to reset sequences for the given models." 202 # No sequence reset required 203 return [] 204 205 OPERATOR_MAPPING = { 206 'exact': '= %s', 207 'iexact': 'LIKE %s', 208 'contains': 'LIKE %s', 209 'icontains': 'LIKE %s', 210 'gt': '> %s', 211 'gte': '>= %s', 212 'lt': '< %s', 213 'lte': '<= %s', 214 'startswith': 'LIKE %s', 215 'endswith': 'LIKE %s', 216 'istartswith': 'LIKE %s', 217 'iendswith': 'LIKE %s', 218 } 219 220 if __name__ == '__main__': 221 from mysite.polls.models import Poll, Choice 222 from django.contrib.auth.models import User 223 from datetime import datetime 224 Poll.objects.all() 225 p = Poll(question="What's up?", pub_date=datetime.now()) 226 p.save() 227 print p.id 228 229 db=DatabaseWrapper() 230 print version() 231 232 -
db/backends/mssql/client.py
1 def runshell(): 2 raise NotImplementedError -
db/backends/mssql/creation.py
1 DATA_TYPES = { 2 'AutoField': 'int IDENTITY (1, 1)', 3 'BooleanField': 'bit', 4 'CharField': 'varchar(%(maxlength)s)', 5 'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)', 6 'DateField': 'datetime', 7 'DateTimeField': 'datetime', 8 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', 9 'FileField': 'varchar(254)', 10 'FilePathField': 'varchar(254)', 11 'FloatField': 'double precision', 12 'ImageField': 'varchar(254)', 13 'IntegerField': 'int', 14 'IPAddressField': 'char(15)', 15 'ManyToManyField': None, 16 'NullBooleanField': 'bit', 17 'OneToOneField': 'int', 18 'PhoneNumberField': 'varchar(20)', 19 #The check must be unique in for the database. Put random so the regresion test not complain about duplicate names 20 'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(creation_counter)s_%(column)s] CHECK ([%(column)s] > 0)', 21 'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(creation_counter)s_%(column)s] CHECK ([%(column)s] > 0)', 22 'SlugField': 'varchar(%(maxlength)s)', 23 'SmallIntegerField': 'smallint', 24 'TextField': 'text', 25 'TimeField': 'datetime', 26 'USStateField': 'varchar(2)', 27 } -
db/backends/mssql/introspection.py
1 def get_table_list(cursor): 2 "Returns a list of table names in the current database." 3 cursor.execute("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'") 4 return [row[2] for row in cursor.fetchall()] 5 6 def _is_auto_field(cursor, table_name, column_name): 7 cursor.execute("SELECT COLUMNPROPERTY( OBJECT_ID('%s'),'%s','IsIdentity')" % (table_name, column_name)) 8 return cursor.fetchall()[0][0] 9 10 def get_table_description(cursor, table_name, identity_check=True): 11 """Returns a description of the table, with the DB-API cursor.description interface. 12 13 The 'auto_check' parameter has been added to the function argspec. 14 If set to True, the function will check each of the table's fields for the 15 IDENTITY property (the IDENTITY property is the MSSQL equivalent to an AutoField). 16 17 When a field is found with an IDENTITY property, it is given a custom field number 18 of -777, which maps to the 'AutoField' value in the DATA_TYPES_REVERSE dict. 19 """ 20 cursor.execute("SELECT TOP 1 * FROM %s" % table_name) 21 cursor.nextset() 22 items = [] 23 if identity_check: 24 for data in cursor.description: 25 if _is_auto_field(cursor, table_name, data[0]): 26 data = list(data) 27 data[1] = -777 28 items.append(list(data)) 29 else: 30 items = cursor.description 31 return items 32 33 def _name_to_index(cursor, table_name): 34 """ 35 Returns a dictionary of {field_name: field_index} for the given table. 36 Indexes are 0-based. 37 """ 38 return dict([(d[0], i) for i, d in enumerate(get_table_description(cursor, table_name, identity_check=False))]) 39 40 def get_relations(cursor, table_name): 41 """ 42 Returns a dictionary of {field_index: (field_index_other_table, other_table)} 43 representing all relationships to the given table. Indexes are 0-based. 44 """ 45 table_index = _name_to_index(cursor, table_name) 46 sql = """SELECT e.COLUMN_NAME AS column_name, 47 c.TABLE_NAME AS referenced_table_name, 48 d.COLUMN_NAME AS referenced_column_name 49 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS a 50 INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS b 51 ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME 52 INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE AS c 53 ON b.UNIQUE_CONSTRAINT_NAME = c.CONSTRAINT_NAME 54 INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS d 55 ON c.CONSTRAINT_NAME = d.CONSTRAINT_NAME 56 INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS e 57 ON a.CONSTRAINT_NAME = e.CONSTRAINT_NAME 58 WHERE a.TABLE_NAME = ? AND 59 a.CONSTRAINT_TYPE = 'FOREIGN KEY'""" 60 cursor = Cursor(cursor.db.connection) 61 cursor.execute(sql, (table_name,)) 62 return dict([(table_index[item[0]], (_name_to_index(cursor, item[1])[item[2]], item[1])) 63 for item in cursor.fetchall()]) 64 65 def get_indexes(cursor, table_name): 66 """ 67 Returns a dictionary of fieldname -> infodict for the given table, 68 where each infodict is in the format: 69 {'primary_key': boolean representing whether it's the primary key, 70 'unique': boolean representing whether it's a unique index} 71 """ 72 sql = """SELECT b.COLUMN_NAME, a.CONSTRAINT_TYPE 73 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS a INNER JOIN 74 INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS b 75 ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME AND 76 a.TABLE_NAME = b.TABLE_NAME 77 WHERE a.TABLE_NAME = ? AND 78 (CONSTRAINT_TYPE = 'PRIMARY KEY' OR 79 CONSTRAINT_TYPE = 'UNIQUE')""" 80 field_names = [item[0] for item in get_table_description(cursor, table_name, identity_check=False)] 81 cursor = Cursor(cursor.db.connection) 82 cursor.execute(sql, (table_name,)) 83 indexes = {} 84 results = {} 85 data = cursor.fetchall() 86 if data: 87 results.update(data) 88 for field in field_names: 89 val = results.get(field, None) 90 indexes[field] = dict(primary_key=(val=='PRIMARY KEY'), unique=(val=='UNIQUE')) 91 return indexes 92 93 # A reference for the values below: 94 # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdcstdatatypeenum.asp 95 DATA_TYPES_REVERSE = { 96 # 8192 : Array , 97 # 128 : Binary , 98 # 9 : IDispatch , 99 # 12 : Variant , 100 # 13 : IUnknown , 101 # 21 : UnsignedBigInt, 102 # 132 : UserDefined , 103 # 0 : Empty , 104 # 136 : Chapter , 105 # 138 : PropVariant , 106 # 204 : VarBinary , 107 # 205 : LongVarBinary , 108 -777: 'AutoField', # Custom number used to identify AutoFields 109 2 : 'SmallIntegerField', # SmallInt 110 3 : 'IntegerField', # Integer 111 4 : 'FloatField', # Single 112 5 : 'FloatField', # Decimal 113 6 : 'FloatField', # Currency 114 7 : 'DateField', # Date 115 8 : 'CharField', # BSTR 116 10 : 'IntegerField', # Error 117 11 : 'BooleanField', # Boolean 118 14 : 'FloatField', # Decimal 119 16 : 'SmallIntegerField', # TinyInt 120 17 : 'PositiveSmallIntegerField', # UnsignedTinyInt 121 18 : 'PositiveSmallIntegerField', # UnsignedSmallInt 122 19 : 'PositiveIntegerField', # UnsignedInt 123 20 : 'IntegerField', # BigInt 124 64 : 'DateTimeField', # FileTime 125 72 : 'CharField', # GUID 126 129 : 'CharField', # Char 127 130 : 'CharField', # WChar 128 131 : 'FloatField', # Numeric 129 133 : 'DateField', # DBDate 130 134 : 'TimeField', # DBTime 131 135 : 'DateTimeField', # DBTimeStamp 132 139 : 'FloatField', # VarNumeric 133 200 : 'CharField', # VarChar 134 201 : 'TextField', # LongVarChar 135 202 : 'CharField', # VarWChar 136 203 : 'TextField', # LongVarWChar 137 } 138 No newline at end of file -
db/backends/util.py
1 from django.conf import settings 1 2 import datetime 2 3 import md5 3 4 from time import time … … 22 23 # formatting with '%' only works with tuples or dicts. 23 24 if not isinstance(params, (tuple, dict)): 24 25 params = tuple(params) 26 # ado_mssql uses '?' for parameter escaping, so all '?' 27 # must be replaced with the standard '%s' if the parameter 28 # substitution is going to work. 29 if settings.DATABASE_ENGINE == 'ado_mssql': 30 sql = sql.replace('?', '%s') 31 # There are many situations that will cause the string 32 # substituion below to fail (e.g. wildcard characters '%' 33 # in LIKE queries). Instead of attempting to figure out 34 # the many variations that can cause an error, the string substition 35 # will be attempted first; if it fails, then the sql 36 # and its parameters will be combined into a string similar to 37 # the one created in the executemany function below. 38 try: 39 sql = sql % tuple(params) 40 except: 41 sql = '%s SQL: %s' % (sql, str(tuple(params))) 25 42 self.db.queries.append({ 26 'sql': sql % params,43 'sql': sql, 27 44 'time': "%.3f" % (stop - start), 28 45 }) 29 46 -
db/models/base.py
239 239 (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.order_with_respect_to.column))) 240 240 db_values.append(getattr(self, self._meta.order_with_respect_to.attname)) 241 241 if db_values: 242 if pk_set and (settings.DATABASE_ENGINE=="ado_mssql" or settings.DATABASE_ENGINE=="mssql"): 243 # You can't insert an auto value into a column unless you do 244 # this in MSSQL 245 # TODO: Only works for auto-id's... how chek it properly? 246 if self._meta.pk.column == 'id': 247 cursor.execute("SET IDENTITY_INSERT %s ON" % \ 248 backend.quote_name(self._meta.db_table)) 249 242 250 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \ 243 251 (backend.quote_name(self._meta.db_table), ','.join(field_names), 244 252 ','.join(placeholders)), db_values) 253 254 if pk_set and (settings.DATABASE_ENGINE=="ado_mssql" or settings.DATABASE_ENGINE=="mssql"): 255 if self._meta.pk.column == 'id': 256 cursor.execute("SET IDENTITY_INSERT %s OFF" %\ 257 backend.quote_name(self._meta.db_table)) 245 258 else: 246 259 # Create a new record with defaults for everything. 247 260 cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % -
db/models/fields/__init__.py
541 541 if value is not None: 542 542 # MySQL will throw a warning if microseconds are given, because it 543 543 # doesn't support microseconds. 544 if settings.DATABASE_ENGINE == 'mysql'and hasattr(value, 'microsecond'):544 if settings.DATABASE_ENGINE in ('mysql', 'ado_mssql','mssql') and hasattr(value, 'microsecond'): 545 545 value = value.replace(microsecond=0) 546 546 value = str(value) 547 547 return Field.get_db_prep_save(self, value) 548 548 549 549 def get_db_prep_lookup(self, lookup_type, value): 550 # MSSQL doesn't like microseconds. 551 if settings.DATABASE_ENGINE in ('mysql', 'ado_mssql','mssql') and hasattr(value, 'microsecond'): 552 value = value.replace(microsecond=0) 550 553 if lookup_type == 'range': 551 554 value = [str(v) for v in value] 552 555 else: … … 908 911 # Casts dates into string format for entry into database. 909 912 if value is not None: 910 913 # MySQL will throw a warning if microseconds are given, because it 911 # doesn't support microseconds. 912 if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'): 914 # doesn't support microseconds. Ditto MSSQL 915 if settings.DATABASE_ENGINE in ('mysql', 'ado_mssql','mssql') \ 916 and hasattr(value, 'microsecond'): 913 917 value = value.replace(microsecond=0) 914 918 if settings.DATABASE_ENGINE == 'oracle': 915 919 # cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field.