Changeset 83 for trunk/dbpickle/dbpickle.py
- Timestamp:
- 03/02/07 19:59:34 (3 years ago)
- Files:
-
- 1 modified
-
trunk/dbpickle/dbpickle.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/dbpickle/dbpickle.py
r82 r83 29 29 30 30 This version handles ForeignKeys which refer to the related model's 31 primary key. ManyToMany and OneToOne relations are not supported. 31 primary key. ManyToMany relations are now supported, but OneToOne 32 relations are not. 32 33 33 34 You can also use you own plugin for pre-processing objects before … … 76 77 def dump(filepath): 77 78 """ 78 Pickle all Django objects from the database and save them into the given file. 79 """ 80 data = {} 79 Pickle all Django objects from the database and save them into the 80 given file. 81 """ 82 objects = {} # model instances 83 m2m_lists = [] # ManyToMany relations between model instances 81 84 for model in models.get_models(): 82 85 meta = model._meta 83 86 app, model_name = meta.app_label, meta.module_name 87 88 # get all many-to-many relation field names for this model 89 m2ms = [m2m.name for m2m in meta.many_to_many] 90 84 91 for obj in model.objects.all(): 85 92 logging.info('dumping %s.%s %s' % (app, model_name, obj)) 86 data[app, model_name, obj._get_pk_val()] = obj 87 cPickle.dump(data, file(filepath, 'w')) 93 pk = obj._get_pk_val() 94 objects[app, model_name, pk] = obj 95 96 for m2m in m2ms: 97 # store many-to-many related objects for every 98 # many-to-many relation of this object 99 foreign_objs = getattr(obj, m2m).all() 100 logging.info('dumping %s.%s.%s x %d' % (app, model_name, m2m, len(foreign_objs))) 101 m2m_lists.append((obj, m2m, tuple(foreign_objs))) 102 103 # pickle all objects and many-to-many relations on disk 104 cPickle.dump((objects, m2m_lists), file(filepath, 'w')) 88 105 89 106 … … 95 112 """ 96 113 114 # load the plugin if specified on the command line 97 115 if pluginpath: 98 116 plugin = load_source('plugin', pluginpath) … … 100 118 plugin = None 101 119 120 # get the hook functions from the plugin 102 121 hooks = {} 103 122 for hookname in 'pre_save', 'pre_walk': 104 123 hooks[hookname] = getattr(plugin, '%s_hook' % hookname, lambda obj: False) 105 124 106 # unpickle objects from file 107 data = cPickle.load(file(filepath)) 108 109 # delete objects from all models to be loaded 110 models = set([obj.__class__ for obj in data.itervalues()]) 125 # unpickle objects and many-to-many relations from disk 126 objects, m2m_lists = cPickle.load(file(filepath)) 127 128 # Find distinct models of all unpickled objects and delete all 129 # objects before loading. Note that models which have not been 130 # dumped are not emptied. 131 models = set( [obj.__class__ for obj in objects.itervalues()] ) 111 132 for model in models: 112 133 for obj in model._default_manager.all(): … … 114 135 115 136 # load all objects 116 while data: 117 key, obj = data.popitem() 118 load_recursive(data, obj, hooks) 137 while objects: 138 key, obj = objects.popitem() 139 load_recursive(objects, obj, hooks) 140 141 # load all many-to-many relations 142 for obj1, m2m, foreign_objs in m2m_lists: 143 meta1 = obj1._meta 144 for obj2 in foreign_objs: 145 meta2 = obj2._meta 146 logging.info('loading ManyToMany %s.%s.%s -> %s.%s.%s' % ( 147 meta1.app_label, meta1.module_name, obj1._get_pk_val(), 148 meta2.app_label, meta2.module_name, obj2._get_pk_val())) 149 getattr(obj1, m2m).add(obj2) 119 150 120 151 load = transaction.commit_on_success(load) 121 152 122 153 123 def load_recursive( data, obj, hooks):154 def load_recursive(objects, obj, hooks): 124 155 """ 125 156 Save the given object into the database. If the object has … … 128 159 """ 129 160 161 meta = obj._meta 162 130 163 hooks['pre_walk'](obj) 131 for field in obj._meta.fields:164 for field in meta.fields: 132 165 if isinstance(field, models.ForeignKey): 133 related_app = field.rel.to._meta.app_label 134 related_model = field.rel.to._meta.module_name 166 related_meta = field.rel.to._meta 167 related_app = related_meta.app_label 168 related_model = related_meta.module_name 135 169 related_pk_val = getattr(obj, field.name+'_id') 136 170 try: 137 related_obj = data.pop((related_app,138 related_model,139 related_pk_val))140 load_recursive( data, related_obj, hooks)171 related_obj = objects.pop((related_app, 172 related_model, 173 related_pk_val)) 174 load_recursive(objects, related_obj, hooks) 141 175 except KeyError: 142 176 logging.debug('probably loaded already: ' 143 177 '%(related_app)s.%(related_model)s ' 144 178 '%(related_pk_val)s' % locals()) 145 if logging.getLogger().level <= logging.INFO: 146 # Must go through this extra step so str(obj) isn't evaluated 147 # if no logging message is to be printed. Sometimes --quiet 148 # is needed to avoid error messages when __repr__ or __str__ 149 # tries to look up objects not yet loaded. 150 logging.info('loading %s' % obj) 179 180 logging.info('loading %s.%s %s' % ( 181 meta.app_label, 182 meta.module_name, 183 obj._get_pk_val())) 151 184 try: 152 185 hooks['pre_save'](obj)
