Changeset 428 for elixir/trunk/elixir
- Timestamp:
- 12/08/08 17:10:58 (3 years ago)
- Location:
- elixir/trunk/elixir
- Files:
-
- 2 modified
-
entity.py (modified) (9 diffs)
-
relationships.py (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
elixir/trunk/elixir/entity.py
r425 r428 9 9 import inspect 10 10 import types 11 import warnings 11 12 12 13 from copy import copy 13 14 14 15 import sqlalchemy 15 from sqlalchemy import Table, Column, Integer, desc, ForeignKey, and_, \16 ForeignKeyConstraint16 from sqlalchemy import Table, Column, Integer, desc, ForeignKey, and_, \ 17 ForeignKeyConstraint 17 18 from sqlalchemy.orm import MapperExtension, mapper, object_session, \ 18 19 EXT_CONTINUE, polymorphic_union, ScopedSession, \ 19 20 ColumnProperty 21 from sqlalchemy.sql import ColumnCollection 20 22 21 23 import elixir … … 67 69 68 70 # columns and constraints waiting for a table to exist 69 self._columns = []71 self._columns = ColumnCollection() 70 72 self.constraints = [] 71 73 … … 270 272 self.add_column(Column(self.version_id_col, Integer)) 271 273 272 args = self.columns+ self.constraints + self.table_args274 args = list(self.columns) + self.constraints + self.table_args 273 275 self.entity.table = Table(self.tablename, self.metadata, 274 276 *args, **kwargs) … … 473 475 check_duplicate = not self.allowcoloverride 474 476 475 if check_duplicate and self.get_column(col.key, False) is not None: 476 raise Exception("Column '%s' already exist in '%s' ! " % 477 (col.key, self.entity.__name__)) 478 self._columns.append(col) 477 if col.key in self._columns: 478 if check_duplicate: 479 raise Exception("Column '%s' already exist in '%s' ! " % 480 (col.key, self.entity.__name__)) 481 else: 482 del self._columns[col.key] 483 self._columns.add(col) 479 484 480 485 if col.primary_key: … … 510 515 #FIXME: something like this is needed to propagate the relationships from 511 516 # parent entities to their children in a concrete inheritance scenario. But 512 # this doesn't work because of the backref matching code. 517 # this doesn't work because of the backref matching code. In most case 518 # (test_concrete.py) it doesn't even happen at all. 513 519 # if self.children and self.inheritance == 'concrete': 514 520 # for child in self.children: … … 531 537 #TODO: this needs to work whether the table is already setup or not 532 538 #TODO: support SA table/autoloaded entity 533 for col in self.columns:534 if col.key == key:535 return col536 if check_missing:537 raise Exception("No column named '%s' found in the table of the"538 "'%s' entity!" % (key, self.entity.__name__))539 return None539 try: 540 return self.columns[key] 541 except KeyError: 542 if check_missing: 543 raise Exception("No column named '%s' found in the table of " 544 "the '%s' entity!" 545 % (key, self.entity.__name__)) 540 546 541 547 def get_inverse_relation(self, rel, check_reverse=True): … … 617 623 primary_keys = property(primary_keys) 618 624 625 def table(self): 626 if self.entity.table: 627 return self.entity.table 628 else: 629 return FakeTable(self) 630 table = property(table) 631 619 632 def primary_key_properties(self): 620 633 """ … … 637 650 return self._pk_props 638 651 primary_key_properties = property(primary_key_properties) 652 653 class FakePK(object): 654 def __init__(self, descriptor): 655 self.descriptor = descriptor 656 657 def columns(self): 658 return self.descriptor.primary_keys 659 columns = property(columns) 660 661 class FakeTable(object): 662 def __init__(self, descriptor): 663 self.descriptor = descriptor 664 self.primary_key = FakePK(descriptor) 665 666 def columns(self): 667 return self.descriptor.columns 668 columns = property(columns) 669 670 def fullname(self): 671 ''' 672 Complete name of the table for the related entity. 673 Includes the schema name if there is one specified. 674 ''' 675 schema = self.descriptor.table_options.get('schema', None) 676 if schema is not None: 677 return "%s.%s" % (schema, self.descriptor.tablename) 678 else: 679 return self.descriptor.tablename 680 fullname = property(fullname) 681 639 682 640 683 class TriggerProxy(object): … … 900 943 desc._pk_col_done = False 901 944 desc.has_pk = False 902 desc._columns = []945 desc._columns = ColumnCollection() 903 946 desc.constraints = [] 904 947 desc.properties = {} -
elixir/trunk/elixir/relationships.py
r427 r428 399 399 400 400 from sqlalchemy import ForeignKeyConstraint, Column, Table, and_ 401 from sqlalchemy.orm import relation, backref 401 from sqlalchemy.orm import relation, backref, class_mapper 402 402 from sqlalchemy.ext.associationproxy import association_proxy 403 403 … … 484 484 def target(self): 485 485 if not self._target: 486 if isinstance(self.of_kind, EntityMeta): 487 self._target = self.of_kind 488 else: 486 if isinstance(self.of_kind, basestring): 489 487 collection = self.entity._descriptor.collection 490 488 self._target = collection.resolve(self.of_kind, self.entity) 489 else: 490 self._target = self.of_kind 491 491 return self._target 492 492 target = property(target) … … 510 510 else: 511 511 check_reverse = not self.kwargs.get('viewonly', False) 512 inverse = self.target._descriptor.get_inverse_relation(self, 513 check_reverse=check_reverse) 514 512 if isinstance(self.target, EntityMeta): 513 inverse = self.target._descriptor.get_inverse_relation( 514 self, check_reverse=check_reverse) 515 else: 516 inverse = None 515 517 self._inverse = inverse 516 518 if inverse and not self.kwargs.get('viewonly', False): … … 599 601 return isinstance(other, (OneToMany, OneToOne)) 600 602 603 def target_table(self): 604 if isinstance(self.target, EntityMeta): 605 return self.target._descriptor.table 606 else: 607 return class_mapper(self.target).local_table 608 target_table = property(target_table) 609 601 610 def create_keys(self, pk): 602 611 ''' … … 615 624 # for that, I need: 616 625 # - the list of primary key columns of the target table (type and name) 626 # - a way to get to a column from its name 617 627 # - the name of the target table 618 target_desc = self.target._descriptor 619 #make sure the target has all its pk set up 620 target_desc.create_pk_cols() 628 #XXX: use a fake table object on pure Elixir case and always introspect 629 #the table as if it was pure SA??? 630 if isinstance(self.target, EntityMeta): 631 # make sure the target has all its pk set up 632 self.target._descriptor.create_pk_cols() 633 634 target_table = self.target_table 621 635 622 636 if source_desc.autoload: … … 629 643 _get_join_clauses(self.entity.table, 630 644 self.colname, None, 631 self.target.table)[0]645 target_table)[0] 632 646 if not self.primaryjoin_clauses: 633 647 colnames = ', '.join(self.colname) … … 645 659 646 660 if self.target_column is None: 647 target_columns = target_ desc.primary_keys661 target_columns = target_table.primary_key.columns 648 662 else: 649 target_columns = [target_ desc.get_column(col)663 target_columns = [target_table.columns[col] 650 664 for col in self.target_column] 651 665 … … 653 667 raise Exception("No primary key found in target table ('%s') " 654 668 "for the '%s' relationship of the '%s' entity." 655 % ( self.target.tablename, self.name,669 % (target_table.name, self.name, 656 670 self.entity.__name__)) 657 671 if self.colname and \ … … 687 701 if col.key == self.name: 688 702 raise ValueError( 689 "ManyToOne named '%s' in '%s' conficts " \690 " with the column of the same name. " \691 "You should probably define the foreign key " \692 "field manually and use the 'field' " \693 "argument on the ManyToOne relationship" \703 "ManyToOne named '%s' in '%s' conficts " 704 " with the column of the same name. " 705 "You should probably define the foreign key " 706 "field manually and use the 'field' " 707 "argument on the ManyToOne relationship" 694 708 % (self.name, self.entity.__name__)) 695 709 … … 704 718 # point to 705 719 fk_refcols.append("%s.%s" % \ 706 (target_ desc.table_fullname, target_col.key))720 (target_table.fullname, target_col.key)) 707 721 708 722 # Build up the primary join. This is needed when you have 709 # several belongs_torelationships between two objects723 # several ManyToOne relationships between two objects 710 724 self.primaryjoin_clauses.append(col == target_col) 711 725 … … 725 739 kwargs = {'uselist': False} 726 740 727 if self.entity.table is self.target .table:741 if self.entity.table is self.target_table: 728 742 # this is needed because otherwise SA has no way to know what is 729 743 # the direction of the relationship since both columns present in … … 733 747 # doesn't help in this case. 734 748 kwargs['remote_side'] = \ 735 [col for col in self.target .table.primary_key.columns]749 [col for col in self.target_table.primary_key.columns] 736 750 737 751 if self.primaryjoin_clauses: … … 882 896 return 883 897 898 #needs: table_options['schema'], autoload, tablename, primary_keys, 899 #entity.__name__, table_fullname 884 900 e1_desc = self.entity._descriptor 885 901 e2_desc = self.target._descriptor
