# Path: dbsync/utils.py
# def get_pk(sa_variant):
#     "Returns the primary key name for the given mapped class or object."
#     mapper = class_mapper(sa_variant) if inspect.isclass(sa_variant) \
#         else object_mapper(sa_variant)
#     return mapper.primary_key[0].key
# 
# def query_model(session, sa_class, only_pk=False):
#     """
#     Returns a query for *sa_class* that doesn't load any relationship
#     attribute.
#     """
#     opts = (noload('*'),)
#     if only_pk:
#         pk = get_pk(sa_class)
#         opts += tuple(
#             defer(prop.key)
#             for prop in class_mapper(sa_class).iterate_properties
#             if isinstance(prop, ColumnProperty)
#             if prop.key != pk)
#     return session.query(sa_class).options(*opts)
# 
# def properties_dict(sa_object):
#     """
#     Returns a dictionary of column-properties for the given SQLAlchemy
#     mapped object.
#     """
#     mapper = object_mapper(sa_object)
#     return dict((prop.key, getattr(sa_object, prop.key))
#                 for prop in mapper.iterate_properties
#                 if isinstance(prop, ColumnProperty))
# 
# Path: dbsync/logs.py
# def get_logger(name):
#     logger = logging.getLogger(name)
#     logger.setLevel(logging.WARNING)
#     loggers.add(logger)
#     if log_handler is not None:
#         logger.addHandler(log_handler)
#     return logger


from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, BigInteger
from sqlalchemy.orm import relationship, backref, validates
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative.api import DeclarativeMeta
from dbsync.lang import *
from dbsync.utils import get_pk, query_model, properties_dict
from dbsync.logs import get_logger
        """
        Performs *operation*, looking for required data in
        *container*, and using *session* to perform it.

        *container* is an instance of
        dbsync.messages.base.BaseMessage.

        *node_id* is the node responsible for the operation, if known
        (else ``None``).

        If at any moment this operation fails for predictable causes,
        it will raise an *OperationError*.
        """
        model = operation.tracked_model
        if model is None:
            raise OperationError("no content type for this operation", operation)

        if operation.command == 'i':
            obj = query_model(session, model).\
                filter(getattr(model, get_pk(model)) == operation.row_id).first()
            pull_obj = container.query(model).\
                filter(attr('__pk__') == operation.row_id).first()
            if pull_obj is None:
                raise OperationError(
                    "no object backing the operation in container", operation)
            if obj is None:
                session.add(pull_obj)
            else:
                # Don't raise an exception if the incoming object is
                # exactly the same as the local one.

# Path: dbsync/utils.py
# def get_pk(sa_variant):
#     "Returns the primary key name for the given mapped class or object."
#     mapper = class_mapper(sa_variant) if inspect.isclass(sa_variant) \
#         else object_mapper(sa_variant)
#     return mapper.primary_key[0].key
# 
# def query_model(session, sa_class, only_pk=False):
#     """
#     Returns a query for *sa_class* that doesn't load any relationship
#     attribute.
#     """
#     opts = (noload('*'),)
#     if only_pk:
#         pk = get_pk(sa_class)
#         opts += tuple(
#             defer(prop.key)
#             for prop in class_mapper(sa_class).iterate_properties
#             if isinstance(prop, ColumnProperty)
#             if prop.key != pk)
#     return session.query(sa_class).options(*opts)
# 
# def properties_dict(sa_object):
#     """
#     Returns a dictionary of column-properties for the given SQLAlchemy
#     mapped object.
#     """
#     mapper = object_mapper(sa_object)
#     return dict((prop.key, getattr(sa_object, prop.key))
#                 for prop in mapper.iterate_properties
#                 if isinstance(prop, ColumnProperty))
# 
# Path: dbsync/logs.py
# def get_logger(name):
#     logger = logging.getLogger(name)
#     logger.setLevel(logging.WARNING)
#     loggers.add(logger)
#     if log_handler is not None:
#         logger.addHandler(log_handler)
#     return logger


# Path: dbsync/models.py
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, BigInteger
from sqlalchemy.orm import relationship, backref, validates
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative.api import DeclarativeMeta
from dbsync.lang import *
from dbsync.utils import get_pk, query_model, properties_dict
from dbsync.logs import get_logger

        """
        Performs *operation*, looking for required data in
        *container*, and using *session* to perform it.

        *container* is an instance of
        dbsync.messages.base.BaseMessage.

        *node_id* is the node responsible for the operation, if known
        (else ``None``).

        If at any moment this operation fails for predictable causes,
        it will raise an *OperationError*.
        """
        model = operation.tracked_model
        if model is None:
            raise OperationError("no content type for this operation", operation)

        if operation.command == 'i':
            obj = query_model(session, model).\
                filter(getattr(model, get_pk(model)) == operation.row_id).first()
            pull_obj = container.query(model).\
                filter(attr('__pk__') == operation.row_id).first()
            if pull_obj is None:
                raise OperationError(
                    "no object backing the operation in container", operation)
            if obj is None:
                session.add(pull_obj)
            else:
                # Don't raise an exception if the incoming object is
                # exactly the same as the local one.

                if properties_dict(obj) == properties_dict(pull_obj):