summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/declarative.py
diff options
context:
space:
mode:
authorJason Kirtland <jek@discorporate.us>2008-05-13 18:14:28 +0000
committerJason Kirtland <jek@discorporate.us>2008-05-13 18:14:28 +0000
commit72dc624bb64e1436ed86dd36f2f1b9d274cb0959 (patch)
tree7f78802ae93478c8495260a88e61e0757ff57ba4 /lib/sqlalchemy/ext/declarative.py
parent6524df92141f8b61f4b7095b92bd2caf678852ed (diff)
downloadsqlalchemy-72dc624bb64e1436ed86dd36f2f1b9d274cb0959.tar.gz
Removed declared_synonym(), pep-8 clean ups.
Diffstat (limited to 'lib/sqlalchemy/ext/declarative.py')
-rw-r--r--lib/sqlalchemy/ext/declarative.py160
1 files changed, 82 insertions, 78 deletions
diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py
index f06f16059..4778b9eba 100644
--- a/lib/sqlalchemy/ext/declarative.py
+++ b/lib/sqlalchemy/ext/declarative.py
@@ -2,9 +2,9 @@
SQLAlchemy object-relational configuration involves the usage of Table,
mapper(), and class objects to define the three areas of configuration.
-declarative moves these three types of configuration underneath the
-individual mapped class. Regular SQLAlchemy schema and ORM constructs are
-used in most cases::
+declarative moves these three types of configuration underneath the individual
+mapped class. Regular SQLAlchemy schema and ORM constructs are used in most
+cases::
from sqlalchemy.ext.declarative import declarative_base
@@ -15,11 +15,10 @@ used in most cases::
id = Column('id', Integer, primary_key=True)
name = Column('name', String(50))
-Above, the ``declarative_base`` callable produces a new base class from
-which all mapped classes inherit from. When the class definition is
-completed, a new ``Table`` and ``mapper()`` have been generated, accessible
-via the ``__table__`` and ``__mapper__`` attributes on the ``SomeClass``
-class.
+Above, the ``declarative_base`` callable produces a new base class from which
+all mapped classes inherit from. When the class definition is completed, a
+new ``Table`` and ``mapper()`` have been generated, accessible via the
+``__table__`` and ``__mapper__`` attributes on the ``SomeClass`` class.
You may omit the names from the Column definitions. Declarative will fill
them in for you::
@@ -29,29 +28,28 @@ them in for you::
id = Column(Integer, primary_key=True)
name = Column(String(50))
-Attributes may be added to the class after its construction, and they will
-be added to the underlying ``Table`` and ``mapper()`` definitions as
+Attributes may be added to the class after its construction, and they will be
+added to the underlying ``Table`` and ``mapper()`` definitions as
appropriate::
SomeClass.data = Column('data', Unicode)
SomeClass.related = relation(RelatedInfo)
Classes which are mapped explicitly using ``mapper()`` can interact freely
-with declarative classes.
+with declarative classes.
-The ``declarative_base`` base class contains a
-``MetaData`` object where newly defined ``Table`` objects are collected.
-This is accessed via the ``metadata`` class level accessor, so to
-create tables we can say::
+The ``declarative_base`` base class contains a ``MetaData`` object where newly
+defined ``Table`` objects are collected. This is accessed via the
+``metadata`` class level accessor, so to create tables we can say::
engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
-The ``Engine`` created above may also be directly associated with the
-declarative base class using the ``engine`` keyword argument, where it will
-be associated with the underlying ``MetaData`` object and allow SQL
-operations involving that metadata and its tables to make use of that
-engine automatically::
+The ``Engine`` created above may also be directly associated with the
+declarative base class using the ``engine`` keyword argument, where it will be
+associated with the underlying ``MetaData`` object and allow SQL operations
+involving that metadata and its tables to make use of that engine
+automatically::
Base = declarative_base(engine=create_engine('sqlite://'))
@@ -59,8 +57,9 @@ Or, as ``MetaData`` allows, at any time using the ``bind`` attribute::
Base.metadata.bind = create_engine('sqlite://')
-The ``declarative_base`` can also receive a pre-created ``MetaData``
-object, which allows a declarative setup to be associated with an already existing traditional collection of ``Table`` objects::
+The ``declarative_base`` can also receive a pre-created ``MetaData`` object,
+which allows a declarative setup to be associated with an already existing
+traditional collection of ``Table`` objects::
mymetadata = MetaData()
Base = declarative_base(metadata=mymetadata)
@@ -68,8 +67,8 @@ object, which allows a declarative setup to be associated with an already existi
Relations to other classes are done in the usual way, with the added feature
that the class specified to ``relation()`` may be a string name. The "class
registry" associated with ``Base`` is used at mapper compilation time to
-resolve the name into the actual class object, which is expected to have
-been defined once the mapper configuration is used::
+resolve the name into the actual class object, which is expected to have been
+defined once the mapper configuration is used::
class User(Base):
__tablename__ = 'users'
@@ -85,9 +84,8 @@ been defined once the mapper configuration is used::
email = Column(String(50))
user_id = Column(Integer, ForeignKey('users.id'))
-Column constructs, since they are just that, are immediately usable, as
-below where we define a primary join condition on the ``Address`` class
-using them::
+Column constructs, since they are just that, are immediately usable, as below
+where we define a primary join condition on the ``Address`` class using them::
class Address(Base)
__tablename__ = 'addresses'
@@ -95,21 +93,19 @@ using them::
id = Column(Integer, primary_key=True)
email = Column(String(50))
user_id = Column(Integer, ForeignKey('users.id'))
- user = relation(User, primaryjoin=user_id==User.id)
-
-When an explicit join condition or other configuration which depends
-on multiple classes cannot be defined immediately due to some classes
-not yet being available, these can be defined after all classes have
-been created. Attributes which are added to the class after
-its creation are associated with the Table/mapping in the same
-way as if they had been defined inline::
-
- User.addresses = relation(Address, primaryjoin=Address.user_id==User.id)
-
-Synonyms are one area where ``declarative`` needs to slightly change the
-usual SQLAlchemy configurational syntax. To define a getter/setter which
-proxies to an underlying attribute, use ``synonym`` with the ``descriptor``
-argument::
+ user = relation(User, primaryjoin=user_id == User.id)
+
+When an explicit join condition or other configuration which depends on
+multiple classes cannot be defined immediately due to some classes not yet
+being available, these can be defined after all classes have been created.
+Attributes which are added to the class after its creation are associated with
+the Table/mapping in the same way as if they had been defined inline::
+
+ User.addresses = relation(Address, primaryjoin=Address.user_id == User.id)
+
+Synonyms are one area where ``declarative`` needs to slightly change the usual
+SQLAlchemy configurational syntax. To define a getter/setter which proxies to
+an underlying attribute, use ``synonym`` with the ``descriptor`` argument::
class MyClass(Base):
__tablename__ = 'sometable'
@@ -130,8 +126,8 @@ class-level expression construct::
session.query(MyClass).filter(MyClass.attr == 'some other value').all()
As an alternative to ``__tablename__``, a direct ``Table`` construct may be
-used. The ``Column`` objects, which in this case require their names,
-will be added to the mapping just like a regular mapping to a table::
+used. The ``Column`` objects, which in this case require their names, will be
+added to the mapping just like a regular mapping to a table::
class MyClass(Base):
__table__ = Table('my_table', Base.metadata,
@@ -145,43 +141,45 @@ This is the preferred approach when using reflected tables, as below::
__table__ = Table('my_table', Base.metadata, autoload=True)
Mapper arguments are specified using the ``__mapper_args__`` class variable.
-Note that the column objects declared on the class are immediately usable,
-as in this joined-table inheritance example::
+Note that the column objects declared on the class are immediately usable, as
+in this joined-table inheritance example::
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
discriminator = Column(String(50))
- __mapper_args__ = {'polymorphic_on':discriminator}
+ __mapper_args__ = {'polymorphic_on': discriminator}
class Engineer(Person):
__tablename__ = 'engineers'
- __mapper_args__ = {'polymorphic_identity':'engineer'}
+ __mapper_args__ = {'polymorphic_identity': 'engineer'}
id = Column(Integer, ForeignKey('people.id'), primary_key=True)
primary_language = Column(String(50))
For single-table inheritance, the ``__tablename__`` and ``__table__`` class
-variables are optional on a class when the class inherits from another
-mapped class.
+variables are optional on a class when the class inherits from another mapped
+class.
As a convenience feature, the ``declarative_base()`` sets a default
-constructor on classes which takes keyword arguments, and assigns them to
-the named attributes::
+constructor on classes which takes keyword arguments, and assigns them to the
+named attributes::
e = Engineer(primary_language='python')
Note that ``declarative`` has no integration built in with sessions, and is
-only intended as an optional syntax for the regular usage of mappers and
-Table objects. A typical application setup using ``scoped_session`` might
-look like::
+only intended as an optional syntax for the regular usage of mappers and Table
+objects. A typical application setup using ``scoped_session`` might look
+like::
engine = create_engine('postgres://scott:tiger@localhost/test')
- Session = scoped_session(sessionmaker(transactional=True, autoflush=False, bind=engine))
+ Session = scoped_session(sessionmaker(transactional=True,
+ autoflush=False,
+ bind=engine))
Base = declarative_base()
Mapped instances then make usage of ``Session`` in the usual way.
-"""
+"""
from sqlalchemy.schema import Table, Column, MetaData
from sqlalchemy.orm import synonym as _orm_synonym, mapper, comparable_property
from sqlalchemy.orm.interfaces import MapperProperty
@@ -190,8 +188,7 @@ from sqlalchemy import util, exceptions
from sqlalchemy.sql import util as sql_util
-__all__ = ['declarative_base', 'synonym_for', 'comparable_using',
- 'declared_synonym']
+__all__ = 'declarative_base', 'synonym_for', 'comparable_using'
class DeclarativeMeta(type):
@@ -213,9 +210,10 @@ class DeclarativeMeta(type):
continue
prop = _deferred_relation(cls, value)
our_stuff[k] = prop
-
+
# set up attributes in the order they were created
- our_stuff.sort(lambda x, y: cmp(our_stuff[x]._creation_order, our_stuff[y]._creation_order))
+ our_stuff.sort(lambda x, y: cmp(our_stuff[x]._creation_order,
+ our_stuff[y]._creation_order))
table = None
if '__table__' not in cls.__dict__:
@@ -248,17 +246,21 @@ class DeclarativeMeta(type):
if inherits:
mapper_args['inherits'] = inherits
if not mapper_args.get('concrete', False) and table:
- # figure out the inherit condition with relaxed rules about nonexistent tables,
- # to allow for ForeignKeys to not-yet-defined tables (since we know for sure that our parent
- # table is defined within the same MetaData)
- mapper_args['inherit_condition'] = sql_util.join_condition(inherits.__table__, table, ignore_nonexistent_tables=True)
-
+ # figure out the inherit condition with relaxed rules
+ # about nonexistent tables, to allow for ForeignKeys to
+ # not-yet-defined tables (since we know for sure that our
+ # parent table is defined within the same MetaData)
+ mapper_args['inherit_condition'] = sql_util.join_condition(
+ inherits.__table__, table,
+ ignore_nonexistent_tables=True)
+
if hasattr(cls, '__mapper_cls__'):
mapper_cls = util.unbound_method_to_callable(cls.__mapper_cls__)
else:
mapper_cls = mapper
- cls.__mapper__ = mapper_cls(cls, table, properties=our_stuff, **mapper_args)
+ cls.__mapper__ = mapper_cls(cls, table, properties=our_stuff,
+ **mapper_args)
return type.__init__(cls, classname, bases, dict_)
def __setattr__(cls, key, value):
@@ -275,22 +277,22 @@ class DeclarativeMeta(type):
type.__setattr__(cls, key, value)
def _deferred_relation(cls, prop):
- if isinstance(prop, PropertyLoader) and isinstance(prop.argument, basestring):
+ if (isinstance(prop, PropertyLoader) and
+ isinstance(prop.argument, basestring)):
arg = prop.argument
def return_cls():
try:
return cls._decl_class_registry[arg]
except KeyError:
- raise exceptions.InvalidRequestError("When compiling mapper %s, could not locate a declarative class named %r. Consider adding this property to the %r class after both dependent classes have been defined." % (prop.parent, arg, prop.parent.class_))
+ raise exceptions.InvalidRequestError(
+ "When compiling mapper %s, could not locate a declarative "
+ "class named %r. Consider adding this property to the %r "
+ "class after both dependent classes have been defined." % (
+ prop.parent, arg, prop.parent.class_))
prop.argument = return_cls
return prop
-def declared_synonym(prop, name):
- """Deprecated. Use synonym(name, descriptor=prop)."""
- return _orm_synonym(name, descriptor=prop)
-declared_synonym = util.deprecated(None, False)(declared_synonym)
-
def synonym_for(name, map_column=False):
"""Decorator, make a Python @property a query synonym for a column.
@@ -303,8 +305,8 @@ def synonym_for(name, map_column=False):
def prop(self):
return 'special sauce'
- The regular ``synonym()`` is also usable directly in a declarative
- setting and may be convenient for read/write properties::
+ The regular ``synonym()`` is also usable directly in a declarative setting
+ and may be convenient for read/write properties::
prop = synonym('col', descriptor=property(_read_prop, _write_prop))
@@ -329,6 +331,7 @@ def comparable_using(comparator_factory):
declarative setting and may be convenient for read/write properties::
prop = comparable_property(MyComparatorType)
+
"""
def decorate(fn):
return comparable_property(comparator_factory, fn)
@@ -347,8 +350,9 @@ def declarative_base(engine=None, metadata=None, mapper=None):
def __init__(self, **kwargs):
for k in kwargs:
if not hasattr(type(self), k):
- raise TypeError('%r is an invalid keyword argument for %s' %
- (k, type(self).__name__))
+ raise TypeError(
+ "%r is an invalid keyword argument for %s" %
+ (k, type(self).__name__))
setattr(self, k, kwargs[k])
return Base