ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙ 4]c @sdZddlZddlZddlmZddlmZddlmZddlmZddlmZdd l m Z d d l m Z d d l m Z d d l mZd dlmZd dlmZd d lm Zd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlm Z d dlm!Z!dZ"dZ#de$fdYZ%e&dZ'd Z(d!ej)e*fd"YZ+d#e+fd$YZ,ddde.d%ede%d&Z/d'Z0d(e.fd)YZ1d*e1fd+YZ2d,e.fd-YZ3e j4e%d.Z5dS(/s1Public API functions and helpers for declarative.iNi(t_add_attribute(t_as_declarative(t_declarative_constructor(t_DeferredMapperConfig(t_del_attribute(t_class_resolveri(texc(t inspection(tutil(t attributes(tcomparable_property(t interfaces(t properties(tsynonym(t_inspect_mapped_class(t_mapper_or_none(tpolymorphic_union(tMetaData(tTable(t hybridmethod(thybridproperty(t OrderedDictcCsQd|jkr%tjd|n||_||_t||j|jdS(sGiven a class, configure the class declaratively, using the given registry, which can be any dictionary, and MetaData object. t_decl_class_registrys4Class %r already has been instrumented declarativelyN(t__dict__RtInvalidRequestErrorRtmetadataRt__name__(tclstregistryR((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pytinstrument_declarative&s   cCs8x1|jdD]"}t|dddk rtSqWtS(sKGiven a class, return True if any of the classes it inherits from has a mapped table, otherwise return False. This is used in declarative mixins to build attributes that behave differently for the base class vs. a subclass in an inheritance hierarchy. .. seealso:: :ref:`decl_mixin_inheritance` it __table__N(t__mro__tgetattrtNonetTruetFalse(Rtclass_((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pythas_inherited_table5s tDeclarativeMetacBs#eZdZdZdZRS(cCs?d|jkr%t|||jntj||||dS(NR(RRttypet__init__(Rt classnametbasestdict_((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyR(IscCst|||dS(N(R(Rtkeytvalue((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyt __setattr__NscCst||dS(N(R(RR,((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyt __delattr__Qs(Rt __module__R(R.R/(((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyR&Hs  csfd}|S(sDecorator that produces an :func:`.orm.synonym` attribute in conjunction with a Python descriptor. The function being decorated is passed to :func:`.orm.synonym` as the :paramref:`.orm.synonym.descriptor` parameter:: class MyClass(Base): __tablename__ = 'my_table' id = Column(Integer, primary_key=True) _job_status = Column("job_status", String(50)) @synonym_for("job_status") @property def job_status(self): return "Status: %s" % self._job_status The :ref:`hybrid properties ` feature of SQLAlchemy is typically preferred instead of synonyms, which is a more legacy feature. .. seealso:: :ref:`synonyms` - Overview of synonyms :func:`.orm.synonym` - the mapper-level function :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an updated approach to augmenting attribute behavior more flexibly than can be achieved with synonyms. cstdd|S(Nt map_columnt descriptor(t _orm_synonym(tfn(R1tname(sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pytdecoratews((R5R1R6((R1R5sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyt synonym_forUs"csfd}|S(s(Decorator, allow a Python @property to be used in query criteria. This is a decorator front end to :func:`~sqlalchemy.orm.comparable_property` that passes through the comparator_factory and the function being decorated:: @comparable_using(MyComparatorType) @property def prop(self): return 'special sauce' The regular ``comparable_property()`` is also usable directly in a declarative setting and may be convenient for read/write properties:: prop = comparable_property(MyComparatorType) cs t|S(N(R (R4(tcomparator_factory(sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyR6s((R8R6((R8sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pytcomparable_using}st declared_attrcBsAeZdZedZdZedZedZ RS(sFMark a class-level method as representing the definition of a mapped property or special declarative member name. @declared_attr turns the attribute into a scalar-like property that can be invoked from the uninstantiated class. Declarative treats attributes specifically marked with @declared_attr as returning a construct that is specific to mapping or declarative table configuration. The name of the attribute is that of what the non-dynamic version of the attribute would be. @declared_attr is more often than not applicable to mixins, to define relationships that are to be applied to different implementors of the class:: class ProvidesUser(object): "A mixin that adds a 'user' relationship to classes." @declared_attr def user(self): return relationship("User") It also can be applied to mapped classes, such as to provide a "polymorphic" scheme for inheritance:: class Employee(Base): id = Column(Integer, primary_key=True) type = Column(String(50), nullable=False) @declared_attr def __tablename__(cls): return cls.__name__.lower() @declared_attr def __mapper_args__(cls): if cls.__name__ == 'Employee': return { "polymorphic_on":cls.type, "polymorphic_identity":"Employee" } else: return {"polymorphic_identity":cls.__name__} cCs/tt|j||j|_||_dS(N(tsuperR:R(t__doc__t _cascading(tselftfgett cascading((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyR(s cCs|jjdd}|dkrtjd|jj rrtj|dkrrt j d|jj|jfn|j|S||kr||S|j|||<}|SdS(Nt_sa_declared_attr_regs^__.+__$sEUnmanaged access of declarative attribute %s from non-mapped class %s( RtgetR!tretmatchR?RR tmanager_of_classRtwarn(tdescR>Rtregtobj((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyt__get__s   cKs t|S(N(t_stateful_declared_attr(Rtkw((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyt _statefulscCs|jdtS(sfMark a :class:`.declared_attr` as cascading. This is a special-use modifier which indicates that a column or MapperProperty-based declared attribute should be configured distinctly per mapped subclass, within a mapped-inheritance scenario. .. warning:: The :attr:`.declared_attr.cascading` modifier has several limitations: * The flag **only** applies to the use of :class:`.declared_attr` on declarative mixin classes and ``__abstract__`` classes; it currently has no effect when used on a mapped class directly. * The flag **only** applies to normally-named attributes, e.g. not any special underscore attributes such as ``__tablename__``. On these attributes it has **no** effect. * The flag currently **does not allow further overrides** down the class hierarchy; if a subclass tries to override the attribute, a warning is emitted and the overridden attribute is skipped. This is a limitation that it is hoped will be resolved at some point. Below, both MyClass as well as MySubClass will have a distinct ``id`` Column object established:: class HasIdMixin(object): @declared_attr.cascading def id(cls): if has_inherited_table(cls): return Column( ForeignKey('myclass.id'), primary_key=True) else: return Column(Integer, primary_key=True) class MyClass(HasIdMixin, Base): __tablename__ = 'myclass' # ... class MySubClass(MyClass): "" # ... The behavior of the above configuration is that ``MySubClass`` will refer to both its own ``id`` column as well as that of ``MyClass`` underneath the attribute named ``some_id``. .. seealso:: :ref:`declarative_inheritance` :ref:`mixin_inheritance_columns` R@(RMR"(R((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyR@s;( RR0R<R#R(RJRRMRR@(((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyR:s ,  RKcBs#eZdZdZdZRS(cKs ||_dS(N(RL(R>RL((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyR(scKs&|jj}|j|t|S(N(RLtcopytupdateRK(R>RLtnew_kw((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyRM!s cCst||jS(N(R:RL(R>R4((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyt__call__&s(RR0R(RMRQ(((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyRKs  tBasec Cs|p t}|r!||_n|dkr<tj}nt|t rU|fpX|} td|d|} t|tr|j | d mapped classes when string names are used to identify classes inside of :func:`.relationship` and others. Allows two or more declarative base classes to share the same registry of class names for simplified inter-base relationships. :param metaclass: Defaults to :class:`.DeclarativeMeta`. A metaclass or __metaclass__ compatible callable to use as the meta type of the generated declarative base class. .. versionchanged:: 1.1 if :paramref:`.declarative_base.cls` is a single class (rather than a tuple), the constructed base class will inherit its docstring. .. seealso:: :func:`.as_declarative` RRR<R(t__mapper_cls__N( RtbindR!tweakreftWeakValueDictionaryt isinstancettupletdictR'R<( RTRtmapperRR5t constructortclass_registryt metaclasst lcl_metadataR*t class_dict((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pytdeclarative_base*sI    c sfd}|S(s Class decorator for :func:`.declarative_base`. Provides a syntactical shortcut to the ``cls`` argument sent to :func:`.declarative_base`, allowing the base class to be converted in-place to a "declarative" base:: from sqlalchemy.ext.declarative import as_declarative @as_declarative() class Base(object): @declared_attr def __tablename__(cls): return cls.__name__.lower() id = Column(Integer, primary_key=True) class MyMappedClass(Base): # ... All keyword arguments passed to :func:`.as_declarative` are passed along to :func:`.declarative_base`. .. seealso:: :func:`.declarative_base` cs!|d<|jdsR'tpjoin(RR(Rtmappers((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyt_create_polymorphic_unions cCs^|j}|jrdSt|j}|j|}|jd|f|j|jjdS(Nt*( t __mapper__twith_polymorphictlisttself_and_descendantsRit_set_with_polymorphict_set_polymorphic_ontcR'(RtmRhRg((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyt__declare_first__s  (RR0R<t classmethodRiRs(((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyRbs+ tAbstractConcreteBasecBsAeZdZeZedZedZedZRS(sdA helper class for 'concrete' declarative mappings. :class:`.AbstractConcreteBase` will use the :func:`.polymorphic_union` function automatically, against all tables mapped as a subclass to this class. The function is called via the ``__declare_last__()`` function, which is essentially a hook for the :meth:`.after_configured` event. :class:`.AbstractConcreteBase` does produce a mapped class for the base class, however it is not persisted to any table; it is instead mapped directly to the "polymorphic" selectable directly and is only used for selecting. Compare to :class:`.ConcreteBase`, which does create a persisted table for the base class. .. note:: The :class:`.AbstractConcreteBase` class does not intend to set up the mapping for the base class until all the subclasses have been defined, as it needs to create a mapping against a selectable that will include all subclass tables. In order to achieve this, it waits for the **mapper configuration event** to occur, at which point it scans through all the configured subclasses and sets up a mapping that will query against all subclasses at once. While this event is normally invoked automatically, in the case of :class:`.AbstractConcreteBase`, it may be necessary to invoke it explicitly after **all** subclass mappings are defined, if the first operation is to be a query against this base class. To do so, invoke :func:`.configure_mappers` once all the desired classes have been configured:: from sqlalchemy.orm import configure_mappers configure_mappers() .. seealso:: :func:`.orm.configure_mappers` Example:: from sqlalchemy.ext.declarative import AbstractConcreteBase class Employee(AbstractConcreteBase, Base): pass class Manager(Employee): __tablename__ = 'manager' employee_id = Column(Integer, primary_key=True) name = Column(String(50)) manager_data = Column(String(40)) __mapper_args__ = { 'polymorphic_identity':'manager', 'concrete':True} configure_mappers() The abstract base class is handled by declarative in a special way; at class configuration time, it behaves like a declarative mixin or an ``__abstract__`` base class. Once classes are configured and mappings are produced, it then gets mapped itself, but after all of its descendants. This is a very unique system of mapping not found in any other SQLAlchemy system. Using this approach, we can specify columns and properties that will take place on mapped subclasses, in the way that we normally do as in :ref:`declarative_mixins`:: class Company(Base): __tablename__ = 'company' id = Column(Integer, primary_key=True) class Employee(AbstractConcreteBase, Base): employee_id = Column(Integer, primary_key=True) @declared_attr def company_id(cls): return Column(ForeignKey('company.id')) @declared_attr def company(cls): return relationship("Company") class Manager(Employee): __tablename__ = 'manager' name = Column(String(50)) manager_data = Column(String(40)) __mapper_args__ = { 'polymorphic_identity':'manager', 'concrete':True} configure_mappers() When we make use of our mappings however, both ``Manager`` and ``Employee`` will have an independently usable ``.company`` attribute:: session.query(Employee).filter(Employee.company.has(id=5)) .. versionchanged:: 1.0.0 - The mechanics of :class:`.AbstractConcreteBase` have been reworked to support relationships established directly on the abstract base, without any special configurational steps. .. seealso:: :class:`.ConcreteBase` :ref:`concrete_inheritance` :ref:`inheritance_concrete_helpers` cCs|jdS(N(t_sa_decl_prepare_nocascade(R((sQ/opt/alt/python27/lib64/python2.7/site-packages/sqlalchemy/ext/declarative/api.pyRsisc st|ddrdStj|}g}t|j}xQ|r|j}|j|jt|}|dk r@|j |q@q@W|j |t |j }xIt|j jD]2\}}||krj|j|j |sZ     (  X %C