Changeset 268

Show
Ignore:
Timestamp:
11/16/07 10:45:36 (6 years ago)
Author:
ged
Message:

allow overriding primary_key columns on autoloaded entities (closes tickets
#20 and #22)

Location:
elixir/trunk
Files:
2 modified

Legend:

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

    r267 r268  
    179179    def create_pk_cols(self): 
    180180        """ 
    181         Create primary_key columns. That is, add columns from belongs_to 
    182         relationships marked as being a primary_key and then add a primary  
    183         key to the table if it hasn't already got one and needs one.  
    184          
    185         This method is "semi-recursive" in that it calls the create_keys  
    186         method on BelongsTo relationships and those in turn call create_pk_cols 
    187         on their target. It shouldn't be possible to have an infinite loop  
    188         since a loop of primary_keys is not a valid situation. 
     181        Create primary_key columns. That is, call the 'create_pk_cols'  
     182        builders then add a primary key to the table if it hasn't already got  
     183        one and needs one.  
     184         
     185        This method is "semi-recursive" in some cases: it calls the  
     186        create_keys method on ManyToOne relationships and those in turn call 
     187        create_pk_cols on their target. It shouldn't be possible to have an  
     188        infinite loop since a loop of primary_keys is not a valid situation. 
    189189        """ 
    190190        if self._pk_col_done: 
    191191            return 
    192192 
    193         if self.autoload: 
    194             return 
    195  
    196193        self.call_builders('create_pk_cols') 
    197194 
    198         if self.parent: 
    199             if self.inheritance == 'multi': 
    200                 # add columns with foreign keys to the parent's primary key  
    201                 # columns  
    202                 parent_desc = self.parent._descriptor 
    203                 for pk_col in parent_desc.primary_keys: 
    204                     colname = "%s_%s" % (self.parent.__name__.lower(), 
    205                                          pk_col.key) 
    206  
    207                     # it seems like SA ForeignKey is not happy being given a  
    208                     # real column object when said column is not yet attached  
    209                     # to a table 
    210                     pk_col_name = "%s.%s" % (parent_desc.tablename, pk_col.key) 
    211                     col = Column(colname, pk_col.type,  
    212                                  ForeignKey(pk_col_name), primary_key=True) 
    213                     self.add_column(col) 
    214         elif not self.has_pk and self.auto_primarykey: 
    215             if isinstance(self.auto_primarykey, basestring): 
    216                 colname = self.auto_primarykey 
    217             else: 
    218                 colname = options.DEFAULT_AUTO_PRIMARYKEY_NAME 
    219              
    220             self.add_column( 
    221                 Column(colname, options.DEFAULT_AUTO_PRIMARYKEY_TYPE,  
    222                        primary_key=True)) 
     195        if not self.autoload: 
     196            if self.parent: 
     197                if self.inheritance == 'multi': 
     198                    # add columns with foreign keys to the parent's primary  
     199                    # key columns  
     200                    parent_desc = self.parent._descriptor 
     201                    for pk_col in parent_desc.primary_keys: 
     202                        colname = "%s_%s" % (self.parent.__name__.lower(), 
     203                                             pk_col.key) 
     204 
     205                        # it seems like SA ForeignKey is not happy being given 
     206                        # a real column object when said column is not yet  
     207                        # attached to a table 
     208                        pk_col_name = "%s.%s" % (parent_desc.tablename,  
     209                                                 pk_col.key) 
     210                        col = Column(colname, pk_col.type,  
     211                                     ForeignKey(pk_col_name), primary_key=True) 
     212                        self.add_column(col) 
     213            elif not self.has_pk and self.auto_primarykey: 
     214                if isinstance(self.auto_primarykey, basestring): 
     215                    colname = self.auto_primarykey 
     216                else: 
     217                    colname = options.DEFAULT_AUTO_PRIMARYKEY_NAME 
     218                 
     219                self.add_column( 
     220                    Column(colname, options.DEFAULT_AUTO_PRIMARYKEY_TYPE,  
     221                           primary_key=True)) 
    223222        self._pk_col_done = True 
    224223 
  • elixir/trunk/tests/test_autoload.py

    r234 r268  
    1919        Column('id', Integer, primary_key=True), 
    2020        Column('name', String(30)), 
    21         Column('color', String(15)), 
    2221        Column('owner_id', Integer, ForeignKey('person.id')), 
    2322        Column('feeder_id', Integer, ForeignKey('person.id'))) 
     
    6665                                tablename='person_category') 
    6766 
    68     elixir.options_defaults.update(dict(autoload=False, shortnames=False)) 
    69  
    7067    metadata.bind = meta.bind 
    7168    setup_all() 
     
    7471def teardown(): 
    7572    cleanup_all() 
     73    elixir.options_defaults.update(dict(autoload=False, shortnames=False)) 
    7674 
    7775#----------- 
     
    8684     
    8785    def test_autoload(self): 
    88         snowball = Animal(name="Snowball II", color="grey") 
     86        snowball = Animal(name="Snowball II") 
    8987        slh = Animal(name="Santa's Little Helper") 
    9088        homer = Person(name="Homer", animals=[snowball, slh], pets=[slh]) 
     
    160158        assert homer in barney.isappreciatedby 
    161159 
     160 
     161def setup_entity_raise(cls): 
     162    try: 
     163        setup_entities([cls]) 
     164    except Exception, e: 
     165        pass 
     166    else: 
     167        assert False, "Exception did not occur setting up %s" % cls.__name__ 
     168 
     169class TestAutoloadOverrideColumn(object): 
     170    def setup(self): 
     171        create_all() 
     172 
     173    def teardown(self): 
     174        drop_all() 
     175 
     176    def test_override_pk_fails(self): 
     177        class Person(Entity): 
     178            id = Field(Integer, primary_key=True) 
     179 
     180        setup_entity_raise(Person) 
     181 
     182    def test_override_non_pk_fails(self): 
     183        class Animal(Entity): 
     184            name = Field(Unicode(30)) 
     185 
     186        setup_entity_raise(Animal) 
     187 
     188    def test_override_pk(self): 
     189        class Person(Entity): 
     190            using_options(allowcoloverride=True) 
     191 
     192            id = Field(Integer, primary_key=True) 
     193 
     194        setup_entities([Person]) 
     195 
     196    def test_override_non_pk(self): 
     197        class Animal(Entity): 
     198            using_options(allowcoloverride=True) 
     199 
     200            name = Field(Unicode(30)) 
     201 
     202        setup_entities([Animal]) 
     203        assert isinstance(Animal.table.columns['name'].type, Unicode) 
     204 
     205