Форум сайта python.su
Помогите ибо не нагуглить…
Хочется сделать так, что-бы существовала общая некая табличная схема. Которую расширяют классы с функциями, которые и являются в конечном счёте моделями.
Вероятно это выглядит так:
Схемы:
from sqlalchemy import (Column, Integer, Unicode, Text, ForeignKey) from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.orm import (relationship, backref) class IDB: __table_args__ = {'mysql_engine':'InnoDB', 'mysql_collate': 'utf8_general_ci', 'extend_existing': True} class PKID: id = Column(Integer, primary_key=True) class SUsers(IDB, PKID): __tablename__ = 'users' username = Column(Unicode(32), unique=True) email = Column(Unicode(32), unique=True) password = Column(Unicode(64)) created = Column(Integer) activity = Column(Integer) @declared_attr def roles(cls): return association_proxy('roles_users', 'roles') @declared_attr def profiles(cls): return relationship("Profiles", uselist=False) class SProfiles(IDB, PKID): __tablename__ = 'profiles' @declared_attr def userid(cls): return Column(Integer, ForeignKey('users.id')) fullname = Column(Unicode(64)) avatar1 = Column(Unicode(32)) avatar2 = Column(Unicode(32)) avatar3 = Column(Unicode(32)) class SRoles(IDB, PKID): __tablename__ = 'roles' name = Column(Unicode(16)) rolesgroup = Column(Unicode(16)) description = Column(Unicode(255)) ordering = Column(Integer) @declared_attr def permissions(cls): return association_proxy('perms_roles', 'permissions') @declared_attr def users(cls): return association_proxy('roles_users', 'users')
import time import datetime from testproject.models import Base from testproject.models.shemas import (SUsers, SProfiles, SRoles, SPermissions, SBlocks, SRolesUsers, SPermissionsRoles) class Users(SUsers, Base): def __init__(self, username, email, password, created, activity=None, profiles=None, roles=None): self.username = username self.email = email self.password = password self.created = created if activity: self.activity = activity if profiles: self.profiles = profiles if roles: self.roles = roles def check_password(self, passwd): return self.password == passwd def datefromtimestamp(self, dateformat='%Y-%m-%d %H:%M:%S'): return str(datetime.datetime.fromtimestamp(self.created).strftime(dateformat)) def activityparams(self, activitytime=300, classactiv='useract', classnoactiv='usernoact', dateformat='%Y-%m-%d %H:%M:%S'): if (int(time.time()) - self.activity) <= activitytime: p1 = classactiv else: p1 = classnoactiv p2 = str(datetime.datetime.fromtimestamp(self.activity).strftime(dateformat)) return (p1, p2) class Profiles(SProfiles, Base): def __init__(self, fullname, register=None, lastlogin=None, expired=None, avatar1=None, avatar2=None, avatar3=None): self.fullname = fullname if avatar1: self.avatar1 = avatar1 if avatar2: self.avatar2 = avatar2 if avatar3: self.avatar3 = avatar3 class Roles(SRoles, Base): def __init__(self, name, rolesgroup, description=None, ordering=None): self.name = name self.rolesgroup = rolesgroup if description: self.description = description if ordering: self.ordering = ordering def shortdesc(self, getsize=68): if len(self.description) >= getsize: return self.description[:getsize] + '...' else: return self.description class Permissions(SPermissions, Base): def __init__(self, permname, description=None, ordering=None): self.permname = permname if description: self.description = description if ordering: self.ordering = ordering def shortdesc(self, getsize=68): if len(self.description) >= getsize: return self.description[:getsize] + '...' else: return self.description
from sqlalchemy import (desc, asc) from testproject.models import DBSession from . import Users, Roles def get_user2(itemid): return DBSession.query(Users).filter(Users.id == itemid).one() def get_user(username): user = DBSession.query(Users).filter(Users.username == username).all() if user: return user[0] else: return None def add_user(): pass #Удалить пользователей по списку def delete_users(delitems): try: for e in delitems: DBSession.query(Users).filter(Users.id == e).delete() transaction.commit() result = 1 except: transaction.rollback() result = 0 return result def get_users(offset=None, limit=None): if offset==None or limit==None: return DBSession.query(Users).all() else: return (DBSession.query(Users).all())[offset:limit]
Офлайн
не понял в чем трудность
там где надо делать запросы импортируешь модели
Офлайн
bismigalisВот он и хрюкает, потому что при изменении названия моделей - Он не может найти связанные модели по схеме.
не понял в чем трудностьтам где надо делать запросы импортируешь модели
class SBlocks(IDB, PKID): __tablename__ = 'blocks' @declared_attr def user_id(cls): return Column(Integer, ForeignKey('users.id')) @declared_attr def permission_id(cls): return Column(Integer, ForeignKey('permissions.id')) @declared_attr def fromuser_id(cls): return Column(Integer, ForeignKey('users.id')) datestart = Column(Integer) dateend = Column(Integer) blockcomment = Column(Unicode(255)) @declared_attr def users(cls): return relationship("Users", uselist=False, primaryjoin="Users.id == Blocks.user_id") @declared_attr def permissions(cls): return relationship("Permissions", uselist=False) @declared_attr def fusers(cls): return relationship("Users", uselist=False, primaryjoin="Users.id == Blocks.fromuser_id")
Офлайн
bismigalis
Я понял в чем проблема. Он захардкорил в схемах во всех связях названия связанных классов. Поэтому при наследовании, если класс, который наследует имеет другое имя, то автоматом накрывается медным тазом связь с другим классом, который тоже, естественно поменяет __name__.
Если я правильно понял проблему, то вижу тут 2 пути:
1. Называть все с одним префиксом и в @declared_attr формировать связь учитывая базовый префикс.
2. Сделать связь на уровне таблиц и не переопределять параметр __table__, а оставить его как в базовом классе.
Офлайн
Правильно я все же понял
Офлайн
А ещё исключение пишет, что проблему можно решить не меняя имя класса, т.е. оставив Users, а указав полный путь. Но как это сделать я не понял…
Офлайн
lightarhont
А ещё исключение пишет, что проблему можно решить не меняя имя класса, т.е. оставив Users, а указав полный путь. Но как это сделать я не понял…
Офлайн
4kpt_IIIНу у админки rbac будет
Вот если бы его увидеть
Офлайн
Исключение, сер, исключение
Офлайн
4kpt_III
Исключение, сер, исключение
2015-04-15 20:17:56,585 ERROR Exception at http://testproject.python/manager/options/control/users
traceback url: http://testproject.python/_debug_toolbar/exception?token=62275c783134555c786236365c783138235c7864635c7865665c7865305c78666527&tb=140692605120016
Traceback (most recent call last):
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid_debugtoolbar-2.0.2-py3.3.egg/pyramid_debugtoolbar/toolbar.py”, line 172, in toolbar_tween
response = _handler(request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid_debugtoolbar-2.0.2-py3.3.egg/pyramid_debugtoolbar/panels/performance.py”, line 55, in resource_timer_handler
result = handler(request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/tweens.py”, line 21, in excview_tween
response = handler(request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/router.py”, line 163, in handle_request
response = view_callable(context, request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/config/views.py”, line 596, in __call__
return view(context, request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/config/views.py”, line 329, in attr_view
return view(context, request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/config/views.py”, line 305, in predicate_wrapper
return view(context, request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/config/views.py”, line 355, in rendered_view
result = view(context, request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/config/views.py”, line 472, in _class_requestonly_view
inst = view(request)
File “/mnt/webserver/pythonproject/testproject/testproject/views/manager/users.py”, line 139, in __init__
Manager.__init__(self, request, 0)
File “/mnt/webserver/pythonproject/testproject/testproject/views/manager/common.py”, line 59, in __init__
user = get_user2(request.authenticated_userid)
File “/mnt/webserver/pythonproject/testproject/testproject/models/manager/rbac/users_func.py”, line 7, in get_user2
return DBSession.query(Users).filter(Users.id == itemid).one()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/scoping.py”, line 150, in do
return getattr(self.registry(), name)(*args, **kwargs)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/session.py”, line 1165, in query
return self._query_cls(entities, self, **kwargs)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/query.py”, line 108, in __init__
self._set_entities(entities)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/query.py”, line 118, in _set_entities
self._set_entity_selectables(self._entities)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/query.py”, line 151, in _set_entity_selectables
ent.setup_entity(*d)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/query.py”, line 3036, in setup_entity
self._with_polymorphic = ext_info.with_polymorphic_mappers
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/util/langhelpers.py”, line 725, in __get__
obj.__dict__ = result = self.fget(obj)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/mapper.py”, line 1877, in _with_polymorphic_mappers
configure_mappers()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/mapper.py”, line 2589, in configure_mappers
mapper._post_configure_properties()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/mapper.py”, line 1694, in _post_configure_properties
prop.init()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/interfaces.py”, line 144, in init
self.do_init()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/relationships.py”, line 1549, in do_init
self._process_dependent_arguments()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/relationships.py”, line 1573, in _process_dependent_arguments
setattr(self, attr, attr_value())
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/ext/declarative/clsregistry.py”, line 271, in __call__
x = eval(self.arg, globals(), self._dict)
File “<string>”, line 1, in <module>
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/util/_collections.py”, line 680, in __missing__
self = val = self.creator(key)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/ext/declarative/clsregistry.py”, line 252, in _access_cls
return _determine_container(key, cls._decl_class_registry)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/ext/declarative/clsregistry.py”, line 236, in _determine_container
value = value.attempt_get(, key)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/ext/declarative/clsregistry.py”, line 89, in attempt_get
(“.”.join(path + ))
sqlalchemy.exc.InvalidRequestError: Multiple classes found for path “Users” in the registry of this declarative base. Please use a fully module-qualified path.
2015-04-15 13:43:20,820 ERROR Exception at http://testproject.python/
traceback url: http://testproject.python/_debug_toolbar/exception?token=62275c7866325c7864645c7831365c786266485c7865653d7e2f5c78626627&tb=139851508717264
Traceback (most recent call last):
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid_debugtoolbar-2.0.2-py3.3.egg/pyramid_debugtoolbar/toolbar.py”, line 172, in toolbar_tween
response = _handler(request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid_debugtoolbar-2.0.2-py3.3.egg/pyramid_debugtoolbar/panels/performance.py”, line 55, in resource_timer_handler
result = handler(request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/tweens.py”, line 21, in excview_tween
response = handler(request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/router.py”, line 163, in handle_request
response = view_callable(context, request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/config/views.py”, line 355, in rendered_view
result = view(context, request)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/pyramid/config/views.py”, line 472, in _class_requestonly_view
inst = view(request)
File “/mnt/webserver/pythonproject/testproject/testproject/views/public/index.py”, line 17, in __init__
Public.__init__(self, request, 0)
File “/mnt/webserver/pythonproject/testproject/testproject/views/public/common.py”, line 38, in __init__
user = get_user2(request.authenticated_userid)
File “/mnt/webserver/pythonproject/testproject/testproject/models/public/common_func.py”, line 6, in get_user2
return DBSession.query(Public_Common_Users).filter(Public_Common_Users.id == itemid).one()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/scoping.py”, line 150, in do
return getattr(self.registry(), name)(*args, **kwargs)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/session.py”, line 1165, in query
return self._query_cls(entities, self, **kwargs)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/query.py”, line 108, in __init__
self._set_entities(entities)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/query.py”, line 118, in _set_entities
self._set_entity_selectables(self._entities)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/query.py”, line 151, in _set_entity_selectables
ent.setup_entity(*d)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/query.py”, line 3036, in setup_entity
self._with_polymorphic = ext_info.with_polymorphic_mappers
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/util/langhelpers.py”, line 725, in __get__
obj.__dict__ = result = self.fget(obj)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/mapper.py”, line 1877, in _with_polymorphic_mappers
configure_mappers()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/mapper.py”, line 2589, in configure_mappers
mapper._post_configure_properties()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/mapper.py”, line 1694, in _post_configure_properties
prop.init()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/interfaces.py”, line 144, in init
self.do_init()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/relationships.py”, line 1550, in do_init
self._setup_join_conditions()
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/relationships.py”, line 1624, in _setup_join_conditions
can_be_synced_fn=self._columns_are_mapped
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/relationships.py”, line 1897, in __init__
self._check_foreign_cols(self.primaryjoin, True)
File “/home/mikhail/.virtualenvs/testproject/lib/python3.3/site-packages/sqlalchemy/orm/relationships.py”, line 2414, in _check_foreign_cols
raise sa_exc.ArgumentError(err)
sqlalchemy.exc.ArgumentError: Could not locate any relevant foreign key columns for primary join condition ‘users.id = blocks.user_id’ on relationship Blocks.users. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or are annotated in the join condition with the foreign() annotation.
Офлайн