Changeset 4962 for main/waeup.sirp/trunk


Ignore:
Timestamp:
1 Feb 2010, 16:25:15 (15 years ago)
Author:
uli
Message:

Remove quick-import tests.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.sirp/trunk/src/waeup/sirp/datacenter.txt

    r4920 r4962  
    257257
    258258    >>> shutil.rmtree(verynewpath)
    259 
    260 Handling imports
    261 ================
    262 
    263 Data centers can find objects ready for CSV imports and associate
    264 appropriate importers with them.
    265 
    266 Getting importers
    267 -----------------
    268 
    269 To do so, data centers look up their parents for the nearest ancestor,
    270 that implements `ICSVDataReceivers` and grab all attributes, that
    271 provide some importer.
    272 
    273 We therefore have to setup a proper scenario first.
    274 
    275 We start by creating a simple thing that is ready for receiving CSV
    276 data:
    277 
    278     >>> class MyCSVReceiver(object):
    279     ...   pass
    280 
    281 Then we create a container for such a CSV receiver:
    282 
    283     >>> import grok
    284     >>> from waeup.sirp.interfaces import ICSVDataReceivers
    285     >>> from waeup.sirp.datacenter import DataCenter
    286     >>> class SomeContainer(grok.Container):
    287     ...   grok.implements(ICSVDataReceivers)
    288     ...   def __init__(self):
    289     ...     self.some_receiver = MyCSVReceiver()
    290     ...     self.other_receiver = MyCSVReceiver()
    291     ...     self.datacenter = DataCenter()
    292 
    293 By implementing `ICSVDataReceivers`, a pure marker interface, we
    294 indicate, that we want instances of this class to be searched for CSV
    295 receivers.
    296 
    297 This root container has two CSV receivers.
    298 
    299 The datacenter is also an attribute of our root container.
    300 
    301 Before we can go into action, we also need an importer, that is able
    302 to import data into instances of MyCSVReceiver:
    303 
    304     >>> from waeup.sirp.csvfile.interfaces import ICSVFile
    305     >>> from waeup.sirp.interfaces import IWAeUPCSVImporter
    306     >>> from waeup.sirp.utils.importexport import CSVImporter
    307     >>> class MyCSVImporter(CSVImporter):
    308     ...   grok.adapts(ICSVFile, MyCSVReceiver)
    309     ...   grok.provides(IWAeUPCSVImporter)
    310     ...   datatype = u'My Stuff'
    311     ...   def doImport(self, filepath, clear_old_data=True,
    312     ...                                overwrite=True):
    313     ...     print "Data imported!"
    314 
    315 We grok the components to get the importer (which is actually an
    316 adapter) registered with the component architechture:
    317 
    318     >>> grok.testing.grok('waeup')
    319     >>> grok.testing.grok_component('MyCSVImporter', MyCSVImporter)
    320     True
    321 
    322 Now we can create an instance of `SomeContainer`:
    323 
    324     >>> mycontainer = SomeContainer()
    325 
    326 As we are not creating real sites and the objects are 'placeless' from
    327 the ZODB point of view, we fake a location by telling the datacenter,
    328 that its parent is the container:
    329 
    330     >>> mycontainer.datacenter.__parent__ = mycontainer
    331     >>> datacenter = mycontainer.datacenter
    332 
    333 When a datacenter is stored in the ZODB, this step will happen
    334 automatically.
    335 
    336 Before we can go on, we have to set a usable path where we can store
    337 files without doing harm:
    338 
    339     >>> os.mkdir('filestore')
    340     >>> filestore = os.path.abspath('filestore')
    341     >>> datacenter.setStoragePath(filestore)
    342     []
    343 
    344 Furthermore we must create a file for possible import, as we will get
    345 only importers, for which also an importable file is available:
    346 
    347     >>> import os
    348     >>> filepath = os.path.join(datacenter.storage, 'mydata.csv')
    349     >>> open(filepath, 'wb').write("""col1,col2
    350     ... 'ATerm','Something'
    351     ... """)
    352 
    353 The datacenter is now able to find the CSV receivers in its parents:
    354 
    355     >>> datacenter.getImporters()
    356     [<MyCSVImporter object at 0x...>, <MyCSVImporter object at 0x...>]
    357 
    358 
    359 Imports with the WAeUP portal
    360 -----------------------------
    361 
    362 The examples above looks complicated, but this is the price for
    363 modularity. If you create a new container type, you can define an
    364 importer and it will be used automatically by other components.
    365 
    366 In the WAeUP portal the only component that actually provides CSV data
    367 importables is the `University` object.
    368 
    369 
    370 Getting imports (not: importers)
    371 --------------------------------
    372 
    373 We can get 'imports':
    374 
    375     >>> datacenter.getPossibleImports()
    376     [(<...DataCenterFile object at 0x...>,
    377       [(<MyCSVImporter object at 0x...>, '...'),
    378        (<MyCSVImporter object at 0x...>, '...')])]
    379 
    380 As we can see, an import is defined here as a tuple of a
    381 DataCenterFile and a list of available importers with an associated
    382 data receiver (the thing where the data should go to).
    383 
    384 The data receiver is given as an ZODB object id (if the data receiver
    385 is persistent) or a simple id (if it is not).
    386 
    387 Clean up:
    388 
    389     >>> import shutil
    390     >>> shutil.rmtree(filestore)
    391 
    392 
    393 Data center helpers
    394 ===================
    395 
    396 Data centers provide several helper methods to make their usage more
    397 convenient.
    398 
    399 
    400 Receivers and receiver ids
    401 --------------------------
    402 
    403 As already mentioned above, imports are defined as triples containing
    404 
    405 * a file to import,
    406 
    407 * an importer to do the import and
    408 
    409 * an object, which should be updated by the data file.
    410 
    411 The latter normally is some kind of container, like a faculty
    412 container or similar. This is what we call a ``receiver`` as it
    413 receives the data from the file via the importer.
    414 
    415 The datacenter finds receivers by looking up its parents for a
    416 component, that implements `ICSVDataReceivers` and scanning that
    417 component for attributes, that can be adapted to `ICSVImporter`.
    418 
    419 I.e., once found an `ICSVDataReceiver` parent, the datacenter gets all
    420 importers that can be applied to attributes of this component. For
    421 each attribute there can be at most one importer.
    422 
    423 When building the importer list for a certain file, we also check,
    424 that the headers of the file comply with what the respective importers
    425 expect. So, if a file contains broken headers, the file won't be
    426 offered for import at all.
    427 
    428 The contexts of the found importers then build our list of available
    429 receivers. This means also, that for each receiver provided by the
    430 datacenter, there is also an importer available.
    431 
    432 If for a potential receiver no importer can be found, this receiver
    433 will be skipped.
    434 
    435 As one type of importer might be able to serve several receivers, we
    436 also have to provide a unique id for each receiver. This is, where
    437 ``receiver ids`` come into play.
    438 
    439 Receiver ids of objects are determined as
    440 
    441 * the ZODB oid of the object if the object is persistent
    442 
    443 * the result of id(obj) otherwise.
    444 
    445 The value won this way is a long integer which we turn into a
    446 string. If the value was get from the ZODB oid, we also prepend it
    447 with a ``z`` to avoid any clash with non-ZODB objects (they might
    448 deliver the same id, although this is *very* unlikely).
Note: See TracChangeset for help on using the changeset viewer.