hll*_*lau 7 python orm sqlalchemy
例如,我在module上有一个声明式的类a:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
addresses = relationship("Address", backref="user")
Run Code Online (Sandbox Code Playgroud)
现在,在模块中,b我想使用映射的实体,但是添加一个方法:
from a import User
class UserWithExtraMethod(User):
def name_capitalized(self):
return self.name.capitalize()
user = UserWithExtraMethod()
print(user.name_capitalized)
Run Code Online (Sandbox Code Playgroud)
但是,当我运行脚本时,会出现以下错误:
InvalidRequestError: Multiple classes found for path "User" in the registry of this declarative base. Please use a fully module-qualified path.
Run Code Online (Sandbox Code Playgroud)
声明用户实体时我错过了什么?我想重用先前声明的实体。
我期望会是这样:
class UserWithExtraMethod(User):
___magic_reuse_previous_mapper__ = True
def name_capitalized(self):
return self.name.capitalize()
Run Code Online (Sandbox Code Playgroud)
除非你有特殊原因需要单独的类,否则你应该这样写:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
addresses = relationship("Address", backref="user")
def name_capitalized(self):
return self.name.capitalize()
Run Code Online (Sandbox Code Playgroud)
由于name_capitalized就 SQLAlchemy 而言并不特殊(它不是 aColumnExpression或类似的),因此映射器完全忽略它。
事实上,还有更好的方法来做到这一点;您的版本适用于 的实例User,但在 sql 表达式中没有用。
from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
class User(Base):
# ... body as before
@hybrid_method
def name_capitalized(self):
return self.name.capitalize()
@name_capitalized.expression
def name_capitalized(cls):
# works for postgresql, other databases spell this differently.
return sqlalchemy.func.initcap(cls.name)
Run Code Online (Sandbox Code Playgroud)
这将允许您执行以下操作:
>>> print Query(User).filter(User.name_capitalized() == "Alice")
SELECT users.id AS users_id, users.name AS users_name
FROM users
WHERE initcap(users.name) = :initcap_1
Run Code Online (Sandbox Code Playgroud)
Hacky,但是为什么不只是User为了您的目的而对类进行猴子修补,而不是继承它呢?
# modude b
from a import User
def name_capitalized(self):
return self.name.capitalize()
User.name_capitalized = name_capitalized
user = User() # and it has extra-method as well
print(user.name_capitalized)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4869 次 |
| 最近记录: |