diff options
Diffstat (limited to 'django/core/db/backends/postgresql.py')
| -rw-r--r-- | django/core/db/backends/postgresql.py | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/django/core/db/backends/postgresql.py b/django/core/db/backends/postgresql.py deleted file mode 100644 index 0bc799c247..0000000000 --- a/django/core/db/backends/postgresql.py +++ /dev/null @@ -1,238 +0,0 @@ -""" -PostgreSQL database backend for Django. - -Requires psycopg 1: http://initd.org/projects/psycopg1 -""" - -from django.core.db import base, typecasts -import psycopg as Database - -DatabaseError = Database.DatabaseError - -try: - # Only exists in python 2.4+ - from threading import local -except ImportError: - # Import copy of _thread_local.py from python 2.4 - from django.utils._threading_local import local - -class DatabaseWrapper(local): - def __init__(self): - self.connection = None - self.queries = [] - - def cursor(self): - from django.conf.settings import DATABASE_USER, DATABASE_NAME, DATABASE_HOST, DATABASE_PORT, DATABASE_PASSWORD, DEBUG, TIME_ZONE - if self.connection is None: - if DATABASE_NAME == '': - from django.core.exceptions import ImproperlyConfigured - raise ImproperlyConfigured, "You need to specify DATABASE_NAME in your Django settings file." - conn_string = "dbname=%s" % DATABASE_NAME - if DATABASE_USER: - conn_string = "user=%s %s" % (DATABASE_USER, conn_string) - if DATABASE_PASSWORD: - conn_string += " password='%s'" % DATABASE_PASSWORD - if DATABASE_HOST: - conn_string += " host=%s" % DATABASE_HOST - if DATABASE_PORT: - conn_string += " port=%s" % DATABASE_PORT - self.connection = Database.connect(conn_string) - self.connection.set_isolation_level(1) # make transactions transparent to all cursors - cursor = self.connection.cursor() - cursor.execute("SET TIME ZONE %s", [TIME_ZONE]) - if DEBUG: - return base.CursorDebugWrapper(cursor, self) - return cursor - - def commit(self): - return self.connection.commit() - - def rollback(self): - if self.connection: - return self.connection.rollback() - - def close(self): - if self.connection is not None: - self.connection.close() - self.connection = None - - def quote_name(self, name): - if name.startswith('"') and name.endswith('"'): - return name # Quoting once is enough. - return '"%s"' % name - -def dictfetchone(cursor): - "Returns a row from the cursor as a dict" - return cursor.dictfetchone() - -def dictfetchmany(cursor, number): - "Returns a certain number of rows from a cursor as a dict" - return cursor.dictfetchmany(number) - -def dictfetchall(cursor): - "Returns all rows from a cursor as a dict" - return cursor.dictfetchall() - -def get_last_insert_id(cursor, table_name, pk_name): - cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name)) - return cursor.fetchone()[0] - -def get_date_extract_sql(lookup_type, table_name): - # lookup_type is 'year', 'month', 'day' - # http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT - return "EXTRACT('%s' FROM %s)" % (lookup_type, table_name) - -def get_date_trunc_sql(lookup_type, field_name): - # lookup_type is 'year', 'month', 'day' - # http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC - return "DATE_TRUNC('%s', %s)" % (lookup_type, field_name) - -def get_limit_offset_sql(limit, offset=None): - sql = "LIMIT %s" % limit - if offset and offset != 0: - sql += " OFFSET %s" % offset - return sql - -def get_random_function_sql(): - return "RANDOM()" - -def get_table_list(cursor): - "Returns a list of table names in the current database." - cursor.execute(""" - SELECT c.relname - FROM pg_catalog.pg_class c - LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace - WHERE c.relkind IN ('r', 'v', '') - AND n.nspname NOT IN ('pg_catalog', 'pg_toast') - AND pg_catalog.pg_table_is_visible(c.oid)""") - return [row[0] for row in cursor.fetchall()] - -def get_table_description(cursor, table_name): - "Returns a description of the table, with the DB-API cursor.description interface." - cursor.execute("SELECT * FROM %s LIMIT 1" % DatabaseWrapper().quote_name(table_name)) - return cursor.description - -def get_relations(cursor, table_name): - """ - Returns a dictionary of {field_index: (field_index_other_table, other_table)} - representing all relationships to the given table. Indexes are 0-based. - """ - cursor.execute(""" - SELECT con.conkey, con.confkey, c2.relname - FROM pg_constraint con, pg_class c1, pg_class c2 - WHERE c1.oid = con.conrelid - AND c2.oid = con.confrelid - AND c1.relname = %s - AND con.contype = 'f'""", [table_name]) - relations = {} - for row in cursor.fetchall(): - try: - # row[0] and row[1] are like "{2}", so strip the curly braces. - relations[int(row[0][1:-1]) - 1] = (int(row[1][1:-1]) - 1, row[2]) - except ValueError: - continue - return relations - -def get_indexes(cursor, table_name): - """ - Returns a dictionary of fieldname -> infodict for the given table, - where each infodict is in the format: - {'primary_key': boolean representing whether it's the primary key, - 'unique': boolean representing whether it's a unique index} - """ - # Get the table description because we only have the column indexes, and we - # need the column names. - desc = get_table_description(cursor, table_name) - # This query retrieves each index on the given table. - cursor.execute(""" - SELECT idx.indkey, idx.indisunique, idx.indisprimary - FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, - pg_catalog.pg_index idx - WHERE c.oid = idx.indrelid - AND idx.indexrelid = c2.oid - AND c.relname = %s""", [table_name]) - indexes = {} - for row in cursor.fetchall(): - # row[0] (idx.indkey) is stored in the DB as an array. It comes out as - # a string of space-separated integers. This designates the field - # indexes (1-based) of the fields that have indexes on the table. - # Here, we skip any indexes across multiple fields. - if ' ' in row[0]: - continue - col_name = desc[int(row[0])-1][0] - indexes[col_name] = {'primary_key': row[2], 'unique': row[1]} - return indexes - -# Register these custom typecasts, because Django expects dates/times to be -# in Python's native (standard-library) datetime/time format, whereas psycopg -# use mx.DateTime by default. -try: - Database.register_type(Database.new_type((1082,), "DATE", typecasts.typecast_date)) -except AttributeError: - raise Exception, "You appear to be using psycopg version 2, which isn't supported yet, because it's still in beta. Use psycopg version 1 instead: http://initd.org/projects/psycopg1" -Database.register_type(Database.new_type((1083,1266), "TIME", typecasts.typecast_time)) -Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", typecasts.typecast_timestamp)) -Database.register_type(Database.new_type((16,), "BOOLEAN", typecasts.typecast_boolean)) - -OPERATOR_MAPPING = { - 'exact': '= %s', - 'iexact': 'ILIKE %s', - 'contains': 'LIKE %s', - 'icontains': 'ILIKE %s', - 'ne': '!= %s', - 'gt': '> %s', - 'gte': '>= %s', - 'lt': '< %s', - 'lte': '<= %s', - 'startswith': 'LIKE %s', - 'endswith': 'LIKE %s', - 'istartswith': 'ILIKE %s', - 'iendswith': 'ILIKE %s', -} - -# This dictionary maps Field objects to their associated PostgreSQL column -# types, as strings. Column-type strings can contain format strings; they'll -# be interpolated against the values of Field.__dict__ before being output. -# If a column type is set to None, it won't be included in the output. -DATA_TYPES = { - 'AutoField': 'serial', - 'BooleanField': 'boolean', - 'CharField': 'varchar(%(maxlength)s)', - 'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)', - 'DateField': 'date', - 'DateTimeField': 'timestamp with time zone', - 'FileField': 'varchar(100)', - 'FilePathField': 'varchar(100)', - 'FloatField': 'numeric(%(max_digits)s, %(decimal_places)s)', - 'ImageField': 'varchar(100)', - 'IntegerField': 'integer', - 'IPAddressField': 'inet', - 'ManyToManyField': None, - 'NullBooleanField': 'boolean', - 'OneToOneField': 'integer', - 'PhoneNumberField': 'varchar(20)', - 'PositiveIntegerField': 'integer CHECK ("%(column)s" >= 0)', - 'PositiveSmallIntegerField': 'smallint CHECK ("%(column)s" >= 0)', - 'SlugField': 'varchar(%(maxlength)s)', - 'SmallIntegerField': 'smallint', - 'TextField': 'text', - 'TimeField': 'time', - 'URLField': 'varchar(200)', - 'USStateField': 'varchar(2)', -} - -# Maps type codes to Django Field types. -DATA_TYPES_REVERSE = { - 16: 'BooleanField', - 21: 'SmallIntegerField', - 23: 'IntegerField', - 25: 'TextField', - 869: 'IPAddressField', - 1043: 'CharField', - 1082: 'DateField', - 1083: 'TimeField', - 1114: 'DateTimeField', - 1184: 'DateTimeField', - 1266: 'TimeField', - 1700: 'FloatField', -} |
