Django

Code

Changeset 2934

Show
Ignore:
Timestamp:
05/17/06 22:36:58 (2 years ago)
Author:
adrian
Message:

Fixed #1904 -- Got postgresql_psycopg2 backend working. Thanks for the patch, germish@gmail.com

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/db/backends/postgresql_psycopg2/base.py

    r2928 r2934  
    66 
    77from django.db.backends import util 
    8 import psycopg2.psycopg1 as Database 
     8import psycopg2 as Database 
    99 
    1010DatabaseError = Database.DatabaseError 
     
    6666def dictfetchone(cursor): 
    6767    "Returns a row from the cursor as a dict" 
     68    # TODO: cursor.dictfetchone() doesn't exist in psycopg2, 
     69    # but no Django code uses this. Safe to remove? 
    6870    return cursor.dictfetchone() 
    6971 
    7072def dictfetchmany(cursor, number): 
    7173    "Returns a certain number of rows from a cursor as a dict" 
     74    # TODO: cursor.dictfetchmany() doesn't exist in psycopg2, 
     75    # but no Django code uses this. Safe to remove? 
    7276    return cursor.dictfetchmany(number) 
    7377 
    7478def dictfetchall(cursor): 
    7579    "Returns all rows from a cursor as a dict" 
     80    # TODO: cursor.dictfetchall() doesn't exist in psycopg2, 
     81    # but no Django code uses this. Safe to remove? 
    7682    return cursor.dictfetchall() 
    7783 
     
    102108    return "DROP CONSTRAINT" 
    103109 
    104 # Register these custom typecasts, because Django expects dates/times to be 
    105 # in Python's native (standard-library) datetime/time format, whereas psycopg 
    106 # use mx.DateTime by default. 
    107 Database.register_type(Database.new_type((1082,), "DATE", util.typecast_date)) 
    108 Database.register_type(Database.new_type((1083,1266), "TIME", util.typecast_time)) 
    109 Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", util.typecast_timestamp)) 
    110 Database.register_type(Database.new_type((16,), "BOOLEAN", util.typecast_boolean)) 
    111  
    112110OPERATOR_MAPPING = { 
    113111    'exact': '= %s', 
  • django/trunk/django/db/backends/postgresql_psycopg2/introspection.py

    r2928 r2934  
    1 from django.db.backends.postgresql.introspection import * 
     1from django.db import transaction 
     2from django.db.backends.postgresql_psycopg2.base import quote_name 
     3 
     4def get_table_list(cursor): 
     5    "Returns a list of table names in the current database." 
     6    cursor.execute(""" 
     7        SELECT c.relname 
     8        FROM pg_catalog.pg_class c 
     9        LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
     10        WHERE c.relkind IN ('r', 'v', '') 
     11            AND n.nspname NOT IN ('pg_catalog', 'pg_toast') 
     12            AND pg_catalog.pg_table_is_visible(c.oid)""") 
     13    return [row[0] for row in cursor.fetchall()] 
     14 
     15def get_table_description(cursor, table_name): 
     16    "Returns a description of the table, with the DB-API cursor.description interface." 
     17    cursor.execute("SELECT * FROM %s LIMIT 1" % quote_name(table_name)) 
     18    return cursor.description 
     19 
     20def get_relations(cursor, table_name): 
     21    """ 
     22    Returns a dictionary of {field_index: (field_index_other_table, other_table)} 
     23    representing all relationships to the given table. Indexes are 0-based. 
     24    """ 
     25    cursor.execute(""" 
     26        SELECT con.conkey, con.confkey, c2.relname 
     27        FROM pg_constraint con, pg_class c1, pg_class c2 
     28        WHERE c1.oid = con.conrelid 
     29            AND c2.oid = con.confrelid 
     30            AND c1.relname = %s 
     31            AND con.contype = 'f'""", [table_name]) 
     32    relations = {} 
     33    for row in cursor.fetchall(): 
     34        try: 
     35            # row[0] and row[1] are like "{2}", so strip the curly braces. 
     36            relations[int(row[0][1:-1]) - 1] = (int(row[1][1:-1]) - 1, row[2]) 
     37        except ValueError: 
     38            continue 
     39    return relations 
     40 
     41def get_indexes(cursor, table_name): 
     42    """ 
     43    Returns a dictionary of fieldname -> infodict for the given table, 
     44    where each infodict is in the format: 
     45        {'primary_key': boolean representing whether it's the primary key, 
     46         'unique': boolean representing whether it's a unique index} 
     47    """ 
     48    # Get the table description because we only have the column indexes, and we 
     49    # need the column names. 
     50    desc = get_table_description(cursor, table_name) 
     51    # This query retrieves each index on the given table. 
     52    cursor.execute(""" 
     53        SELECT idx.indkey, idx.indisunique, idx.indisprimary 
     54        FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, 
     55            pg_catalog.pg_index idx 
     56        WHERE c.oid = idx.indrelid 
     57            AND idx.indexrelid = c2.oid 
     58            AND c.relname = %s""", [table_name]) 
     59    indexes = {} 
     60    for row in cursor.fetchall(): 
     61        # row[0] (idx.indkey) is stored in the DB as an array. It comes out as 
     62        # a string of space-separated integers. This designates the field 
     63        # indexes (1-based) of the fields that have indexes on the table. 
     64        # Here, we skip any indexes across multiple fields. 
     65        if ' ' in row[0]: 
     66            continue 
     67        col_name = desc[int(row[0])-1][0] 
     68        indexes[col_name] = {'primary_key': row[2], 'unique': row[1]} 
     69    return indexes 
     70 
     71# Maps type codes to Django Field types. 
     72DATA_TYPES_REVERSE = { 
     73    16: 'BooleanField', 
     74    21: 'SmallIntegerField', 
     75    23: 'IntegerField', 
     76    25: 'TextField', 
     77    869: 'IPAddressField', 
     78    1043: 'CharField', 
     79    1082: 'DateField', 
     80    1083: 'TimeField', 
     81    1114: 'DateTimeField', 
     82    1184: 'DateTimeField', 
     83    1266: 'TimeField', 
     84    1700: 'FloatField', 
     85