我将尝试提出一个问题。
现在我正在学习 Python 和 SQLAlchemy 为自己做一个项目。创建了一个表User:
Model = declarative_base()
class User(Model):
__tablename__ = "users"
id = Column(Integer, primary_key = True)
nickname = Column(String)
email = Column(String)
password = Column(String)
添加了一些条目。
假设现在我想检查是否有任何用户使用指定的电子邮件?我执行以下操作:
bool(session.query(exists().where(User.email == email)).scalar())
至于我——这段代码绝对不可读。因此,我将它(以及用于处理基础的其他类似功能)移到一个单独的类Users中。我在应用程序逻辑中根据需要调用它们。
class Users:
def exists(email):
return bool(session.query(exists().where(User.email == email)).scalar())
def add(nick, email, password):
pass # Тут код
def email_exists(email):
pass # Тут код
def update(id, nick, email, password):
pass # Тут код
现在我想明白了。我在骑自行车方面进步了多少?如何做到“好”?我已经打开了几个开源项目,但还没有看到类似的东西。因此,我逐渐意识到这不是正确的方法。
我曾经这样做过。就像我一样 - 模型方法的正常实施。一个好的解决方案是创建一个可以从中继承其他模型的基类,并在方法本身中添加必要的逻辑。
为了我的需要,使用 Flask 框架,我写了这样一个装置:
现在我明白了很多事情都是不必要的和错误的,但无论如何,对于自我发展来说,这是一次很好的经历。
首先,那些在所有模型中重复的字段(id、created_at、modified_al)被描述一次。
其次,继承了create(),带有一些异常处理。
第三,处理after_insert、after_update、after_delete ORM事件(我的实现方法已经过时了),返回数据给redis。我这样做是为了“实时”数据传输(通知、仪表板中的数据更新等)
第四,
__repr__这也是所有车型通用的。此外,您可以在此处添加所谓的“软删除”,这将允许您永远不从数据库中删除数据,以及从数据库中“不删除”的方法,即所有且仅删除的数据。
如有必要,您可以想到一堆事情。
最终,一次实现的基类将在模型中节省大量时间和空间。
一般来说,该方法符合 OO 的精神,但通常不应在模型中使用会话,特别是因为您的示例中有一个全局变量会话,最好将其传递给方法 /财产。
在你的例子中,我认为有些不正确 - 示例中指示的方法应该是 classmethod - 类方法,因为它们没有绑定到实体实例
如果可能的话,我会建议您制作混合属性/方法而不是常规属性/方法 - 以防万一。突然之间,您需要在最终请求中使用一段属性逻辑来发出请求,它们有时会增加可读性。