2012-06-07 70 views
2

你用什麼方法在django中設置數據庫級別的默認值?爲django中的字段設置數據庫級別的默認值?

我明白這是一個django wontfix的決定,但是如果爲特定的後端(postgres)編寫的話,一定會有一些想法實現這一點。

我想通過python提供這個功能,所以我不想使用/sql/.sql文件。

我想我可能會設置在現有領域的屬性,如:

foo = models.CharField(max_length=256, blank=True) 
foo.db_default = '' 

然後穿過田野過濾和構建ALTER COLUMN SET DEFAULT查詢。

哪裏可以提出這個問題呢?文檔說不要改變post_syncdb鉤子中的數據庫。

任何想法在哪裏把這個動作?我也在想我可以動態生成sql/.sql文件。管理命令總比沒有好。自動會很好。嗯,我不知道post_syncdb可以生成SQL文件及時執行?將測試。

回答

0

我試過在做post_syncdb但是使用.sql文件已經太晚了。與class_prepared掛鉤的時間爲syncdb,但我意識到我過於複雜的事情。我不妨在模型實例化時運行一次代碼。

我最終提出了一個直接的解決方案,在6個月內我可以很容易地理解,當我需要再次擺弄這些時。

def db_default(field, db_default): 
    """ 
    Set attribute __db_default for signal to set default values with. 
    """ 
    field.__db_default = db_default 
    return field 

class OrderShipLog(models.Model): 
    date = db_default(models.DateTimeField(), 'now()') 

def generate_default_sql(model): 
    """ 
    Generate SQL for postgresql_psycopg2 default values because the shipping 
    database post doesn't guarantee posting certain fields but id like them all to be strings. 
    """ 
    db_fields = filter(lambda x: hasattr(x, '__db_default'), model._meta.fields) 
    db_table = model._meta.db_table 
    modelname = model._meta.object_name 

    sql_dir = os.path.join(os.path.dirname(__file__), 'sql/') 
    sql_filename = os.path.join(sql_dir, '{modelname}.postgresql_psycopg2.sql'.format(
     modelname=modelname.lower())) 

    from django.db import connection 
    if not db_table in connection.introspection.table_names(): 
     print >> sys.stderr, "{0} not in introspected table list; creating db default sql file : {1}".format(db_table, sql_filename) 
     try: 
      if not os.path.exists(sql_dir): 
       os.makedirs(sql_dir) 

      with open(sql_filename, 'w+') as f: 
       for field in db_fields: 
        attname, db_column = field.get_attname_column() 
        if not field.__db_default: 
         raise Exception("Must enter value for field {modelname}.{field}.__db_default".format(
          modelname=modelname, 
          field=attname)) 
        f.write('ALTER TABLE {db_table} ALTER COLUMN {db_column} SET DEFAULT {default};\n'.format(
         db_table=db_table, 
         db_column=db_column, 
         default=field.__db_default, 
         )) 
     except Exception, e: 
      print >> sys.stderr, "Could not generate SQL file. Manually set the defaults! {0}\n".format(e) * 10 

generate_default_sql(OrderShipLog) 
相關問題