在sqlalchemy中向一个decorative类添加一个方法有什么副作用吗



我曾问过这个问题:如何创建一个表条目的实例,但不添加到ponyorm中?我问我如何在不立即添加的情况下创建定义为ponyorm表表示的类的实例。通过使用sqlalchemy,在session实例上需要显式add,我认为我通过使用以下代码成功了。

我首先创建了一个名为AddInstance的类,它有一个add方法,然后在我的所有表定义中继承它。这似乎很有效(即,只有在我想相对容易的情况下,我才能创建一个类的实例并添加它(,但我不确定是否有任何意外的副作用,或者这与最佳实践相去甚远。

from sqlalchemy import create_engine                                               
from sqlalchemy.ext.declarative import declarative_base                         
from sqlalchemy.orm import sessionmaker, relationship                           
from sqlalchemy import Column, String, Integer                                  

engine = create_engine('sqlite:///:memory:')                                    
Base = declarative_base()                                                       
Session = sessionmaker(bind=engine)                                                

class AddInstance:                                                                 
def add(self):                                                              
session = Session()                                                        
session.add(self)                                                       
session.commit()

class Pizza(Base, AddInstance):                                                    
__tablename__ = 'pizzas'                                                       
id = Column(Integer, primary_key=True)                                         
name = Column(String(50))                                                      
toppings = relationship('Topping', back_populates='name')                      

class Topping(Base, AddInstance):                                                  
__tablename__ = 'fruits'                                                       
id = Column(Integer, primary_key=True)                                         
name = Column(String(50))                                                      
pizzas = relationship('Pizza', back_populates='name')                          

Base.metadata.create_all(engine)                                                   

不会有任何副作用,SQLAlchemy明确支持添加方法。这些方法是在mixin类上定义还是直接在从Base派生的类上定义都无关紧要。

引用SQLAlchemy对象关系教程文档部分:

除了映射过程对我们的类所做的之外,该类在其他方面主要是一个普通的Python类,我们可以定义应用程序所需的任何数量的普通属性和方法

(粗体强调矿(。

有很多代码库的例子可以做完全相同的事情。Flask SQLAlchemy提供了一个Model基类来添加query属性(在创建声明性基类时设置(,例如,可以直接从模型类中执行Topping.query(...)

add()方法确实有缺点:它创建了一个新的Session()实例,只是为了添加和提交对象。这使它处于正常会话状态管理语义之外,如果您想对新创建的对象执行任何其他操作,则必须将其合并到现有会话中。

代码调用SQLAlchemy对象的通常最佳实践是创建一个会话来管理事务,这是一组必须成功或失败的操作。这包括创建对象;在许多实际应用程序中,当依赖于这些行的其他操作失败时,您希望避免在数据库中创建额外的行。.add()方法在一个单独的事务中无条件地提交每个对象。您可能需要重新访问此模式。

最新更新