Changeset 490 for elixir/trunk/elixir

Show
Ignore:
Timestamp:
10/02/09 12:06:14 (3 years ago)
Author:
ged
Message:

Dropped support for python 2.3, SQLAlchemy 0.4 and deprecated stuff from Elixir
0.7

Location:
elixir/trunk/elixir
Files:
2 removed
5 modified

Legend:

Unmodified
Added
Removed
  • elixir/trunk/elixir/__init__.py

    r416 r490  
    8686    '''Setup the table and mapper of all entities in the default entity 
    8787    collection. 
    88  
    89     This is called automatically if any entity of the collection is configured 
    90     with the `autosetup` option and it is first accessed, 
    91     instanciated (called) or the create_all method of a metadata containing 
    92     tables from any of those entities is called. 
    9388    ''' 
    9489    setup_entities(entities) 
  • elixir/trunk/elixir/collection.py

    r439 r490  
    33''' 
    44import sys 
    5  
    6 from elixir.py23compat import rsplit 
    75 
    86# default entity collection 
     
    3331        "source" entity when resolving relationship targets. 
    3432        ''' 
    35         path = rsplit(key, '.', 1) 
     33        path = key.rsplit('.', 1) 
    3634        classname = path.pop() 
    3735        if path: 
  • elixir/trunk/elixir/entity.py

    r480 r490  
    33``EntityMeta``. 
    44''' 
    5  
    6 from py23compat import sorted 
    75 
    86import sys 
     
    499497            self.has_pk = True 
    500498 
    501         # Autosetup triggers shouldn't be active anymore at this point, so we 
    502         # can theoretically access the entity's table safely. But the problem 
    503         # is that if, for some reason, the trigger removal phase didn't 
    504         # happen, we'll get an infinite loop. So we just make sure we don't 
    505         # get one in any case. 
    506         table = type.__getattribute__(self.entity, 'table') 
     499        table = self.entity.table 
    507500        if table is not None: 
    508501            if check_duplicate and col.key in table.columns.keys(): 
     
    691684 
    692685 
    693 class TriggerProxy(object): 
    694     """ 
    695     A class that serves as a "trigger" ; accessing its attributes runs 
    696     the setup_all function. 
    697  
    698     Note that the `setup_all` is called on each access of the attribute. 
    699     """ 
    700  
    701     def __init__(self, class_, attrname): 
    702         self.class_ = class_ 
    703         self.attrname = attrname 
    704  
    705     def __getattr__(self, name): 
    706         elixir.setup_all() 
    707         #FIXME: it's possible to get an infinite loop here if setup_all doesn't 
    708         #remove the triggers for this entity. This can happen if the entity is 
    709         #not in the `entities` list for some reason. 
    710         proxied_attr = getattr(self.class_, self.attrname) 
    711         return getattr(proxied_attr, name) 
    712  
    713     def __repr__(self): 
    714         proxied_attr = getattr(self.class_, self.attrname) 
    715         return "<TriggerProxy (%s)>" % (self.class_.__name__) 
    716  
    717  
    718 class TriggerAttribute(object): 
    719  
    720     def __init__(self, attrname): 
    721         self.attrname = attrname 
    722  
    723     def __get__(self, instance, owner): 
    724         #FIXME: it's possible to get an infinite loop here if setup_all doesn't 
    725         #remove the triggers for this entity. This can happen if the entity is 
    726         #not in the `entities` list for some reason. 
    727         elixir.setup_all() 
    728         return getattr(owner, self.attrname) 
    729  
    730686def is_entity(cls): 
    731687    """ 
     
    774730        prop.attach(cls, name) 
    775731 
    776     # Process mutators. Needed before _install_autosetup_triggers so that 
    777     # we know of the metadata (and whether the entity is autosetuped or not). 
     732    # Process mutators 
    778733    process_mutators(cls) 
    779734 
    780735    # setup misc options here (like tablename etc.) 
    781736    desc.setup_options() 
    782  
    783     # create trigger proxies 
    784     # TODO: support entity_name... It makes sense only for autoloaded 
    785     # tables for now, and would make more sense if we support "external" 
    786     # tables 
    787     if desc.autosetup: 
    788         _install_autosetup_triggers(cls) 
    789737 
    790738 
     
    808756        instrument_class(cls) 
    809757 
    810     def __call__(cls, *args, **kwargs): 
    811         if cls._descriptor.autosetup and not hasattr(cls, '_setup_done'): 
    812             elixir.setup_all() 
    813         return type.__call__(cls, *args, **kwargs) 
    814  
    815758    def __setattr__(cls, key, value): 
    816759        if isinstance(value, Property): 
     
    824767 
    825768 
    826 def _install_autosetup_triggers(cls, entity_name=None): 
    827     #TODO: move as much as possible of those "_private" values to the 
    828     # descriptor, so that we don't mess the initial class. 
    829     warnings.warn("The 'autosetup' option on entities is deprecated. " 
    830         "Please call setup_all() manually after all your entities have been " 
    831         "declared.", DeprecationWarning, stacklevel=4) 
    832     tablename = cls._descriptor.tablename 
    833     schema = cls._descriptor.table_options.get('schema', None) 
    834     cls._table_key = sqlalchemy.schema._get_table_key(tablename, schema) 
    835  
    836     table_proxy = TriggerProxy(cls, 'table') 
    837  
    838     md = cls._descriptor.metadata 
    839     md.tables[cls._table_key] = table_proxy 
    840  
    841     # We need to monkeypatch the metadata's table iterator method because 
    842     # otherwise it doesn't work if the setup is triggered by the 
    843     # metadata.create_all(). 
    844     # This is because ManyToMany relationships add tables AFTER the list 
    845     # of tables that are going to be created is "computed" 
    846     # (metadata.tables.values()). 
    847     # see: 
    848     # - table_iterator method in MetaData class in sqlalchemy/schema.py 
    849     # - visit_metadata method in sqlalchemy/ansisql.py 
    850     if SA05orlater: 
    851         warnings.warn( 
    852             "The automatic setup via metadata.create_all() through " 
    853             "the autosetup option doesn't work with SQLAlchemy 0.5 and later!") 
    854     else: 
    855         # SA 0.6 does not use table_iterator anymore (it was already deprecated 
    856         # since SA 0.5.0) 
    857         original_table_iterator = md.table_iterator 
    858         if not hasattr(original_table_iterator, 
    859                        '_non_elixir_patched_iterator'): 
    860             def table_iterator(*args, **kwargs): 
    861                 elixir.setup_all() 
    862                 return original_table_iterator(*args, **kwargs) 
    863             table_iterator.__doc__ = original_table_iterator.__doc__ 
    864             table_iterator._non_elixir_patched_iterator = \ 
    865                 original_table_iterator 
    866             md.table_iterator = table_iterator 
    867  
    868     #TODO: we might want to add all columns that will be available as 
    869     #attributes on the class itself (in SA 0.4+). This is a pretty 
    870     #rare usecase, as people will normally hit the query attribute before the 
    871     #column attributes, but I've seen people hitting this problem... 
    872     for name in ('c', 'table', 'mapper', 'query'): 
    873         setattr(cls, name, TriggerAttribute(name)) 
    874  
    875     cls._has_triggers = True 
    876  
    877  
    878 def _cleanup_autosetup_triggers(cls): 
    879     if not hasattr(cls, '_has_triggers'): 
    880         return 
    881  
    882     for name in ('table', 'mapper'): 
    883         setattr(cls, name, None) 
    884  
    885     for name in ('c', 'query'): 
    886         delattr(cls, name) 
    887  
    888     desc = cls._descriptor 
    889     md = desc.metadata 
    890  
    891     # the fake table could have already been removed (namely in a 
    892     # single table inheritance scenario) 
    893     md.tables.pop(cls._table_key, None) 
    894  
    895     # restore original table iterator if not done already 
    896     if not SA05orlater: 
    897         if hasattr(md.table_iterator, '_non_elixir_patched_iterator'): 
    898             md.table_iterator = \ 
    899                 md.table_iterator._non_elixir_patched_iterator 
    900  
    901     del cls._has_triggers 
    902  
    903  
    904769def setup_entities(entities): 
    905770    '''Setup all entities in the list passed as argument''' 
     
    912777            if isinstance(attr, Property): 
    913778                delattr(entity, name) 
    914  
    915         if entity._descriptor.autosetup: 
    916             _cleanup_autosetup_triggers(entity) 
    917779 
    918780    for method_name in ( 
     
    940802    """ 
    941803    Try to revert back the list of entities passed as argument to the state 
    942     they had just before their setup phase. It will not work entirely for 
    943     autosetup entities as we need to remove the autosetup triggers. 
     804    they had just before their setup phase. 
    944805 
    945806    As of now, this function is *not* functional in that it doesn't revert to 
     
    953814    for entity in entities: 
    954815        desc = entity._descriptor 
    955         if desc.autosetup: 
    956             _cleanup_autosetup_triggers(entity) 
    957816 
    958817        if hasattr(entity, '_setup_done'): 
  • elixir/trunk/elixir/options.py

    r484 r490  
    116116|                     | that module.                                          | 
    117117+---------------------+-------------------------------------------------------+ 
    118 | ``autosetup``       | DEPRECATED. Specify whether that entity will contain  | 
    119 |                     | automatic setup triggers.                             | 
    120 |                     | That is if this entity will be                        | 
    121 |                     | automatically setup (along with all other entities    | 
    122 |                     | which were already declared) if any of the following  | 
    123 |                     | condition happen: some of its attributes are accessed | 
    124 |                     | ('c', 'table', 'mapper' or 'query'), instanciated     | 
    125 |                     | (called) or the create_all method of this entity's    | 
    126 |                     | metadata is called. Defaults to ``False``.            | 
    127 +---------------------+-------------------------------------------------------+ 
    128118| ``allowcoloverride``| Specify whether it is allowed to override columns.    | 
    129119|                     | By default, Elixir forbids you to add a column to an  | 
     
    214204# 
    215205options_defaults = dict( 
    216     autosetup=False, 
    217206    inheritance='single', 
    218207    polymorphic=True, 
  • elixir/trunk/elixir/relationships.py

    r488 r490  
    303303| ``table_kwargs``   | A dictionary holding any other keyword argument you    | 
    304304|                    | might want to pass to the underlying Table object.     | 
    305 +--------------------+--------------------------------------------------------+| ``column_format``  | DEPRECATED. Specify an alternate format string for     | 
    306 |                    | naming the                                             | 
    307 |                    | columns in the mapping table.  The default value is    | 
    308 |                    | defined in ``elixir.options.M2MCOL_NAMEFORMAT``.  You  | 
    309 |                    | will be passed ``tablename``, ``key``, and ``entity``  | 
    310 |                    | as arguments to the format string.                     | 
    311305+--------------------+--------------------------------------------------------+ 
    312306 
     
    839833                 ondelete=None, onupdate=None, 
    840834                 table=None, schema=None, 
    841                  column_format=None, 
    842835                 filter=None, 
    843836                 table_kwargs=None, 
     
    858851        self.schema = schema 
    859852 
    860         if column_format: 
    861             warnings.warn("The 'column_format' argument on ManyToMany " 
    862                 "relationships is deprecated. Please use the 'local_colname' " 
    863                 "and/or 'remote_colname' arguments if you want custom " 
    864                 "column names for this table only, or modify " 
    865                 "options.M2MCOL_NAMEFORMAT if you want a custom format for " 
    866                 "all ManyToMany tables", DeprecationWarning, stacklevel=3) 
    867         self.column_format = column_format or options.M2MCOL_NAMEFORMAT 
     853        #TODO: this can probably be simplified/moved elsewhere since the 
     854        #argument disappeared 
     855        self.column_format = options.M2MCOL_NAMEFORMAT 
    868856        if not hasattr(self.column_format, '__call__'): 
    869857            # we need to store the format in a variable so that the 
     
    890878 
    891879        super(ManyToMany, self).__init__(of_kind, *args, **kwargs) 
    892  
    893     def get_table(self): 
    894         warnings.warn("The secondary_table attribute on ManyToMany objects is " 
    895                       "deprecated. You should rather use the table attribute.", 
    896                       DeprecationWarning, stacklevel=2) 
    897         return self.table 
    898     secondary_table = property(get_table) 
    899880 
    900881    def match_type_of(self, other):