sqlalchemy: 仅插入行的一部分

1 投票
2 回答
5468 浏览
提问于 2025-04-17 17:45

我刚开始学习sqlalchemy,遇到了一些问题。
我找不到只插入新行部分内容的方法。
使用session.add()可以插入一行数据,但前提是我得提供所有的列。如果我只想提供一些列呢?

在网上我看到一些地方建议我使用.insert()

sqlalchemy.sql.expression.insert(table, values=None, inline=False, **kwargs)

(我刚接触编程,所以对这些代码行还不是很理解)

我导入了

import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean
from sqlalchemy.orm import relationship, backref
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql.expression import insert

Base = declarative_base()
engine = create_engine('sqlite:///test.db')

class Users(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)
    password = Column(String)
    email = Column(String)

    def __init__(self, name, password, email):
        self.name = name
        self.password = password
        self.email = email

Session = sessionmaker(bind=engine)
Session.configure(bind=engine)
session = Session()

session.add(users.insert().values(name="some name"))

但是这最后一行总是给我报错,(Users没有insert这个属性)
我到底哪里做错了呢?

2 个回答

0

所谓“部分插入”,其实和“完全插入”是一样的,只不过你没有提供的值会被留作NULL。数据库可以把这些NULL的值替换成你在表结构中为那些没填的列指定的默认值。

在SQLAlchemy中,这意味着你可以把那些列设置为None;而且你甚至不需要特别去做这件事。

需要注意的是,你的Users类里其实不需要有__init__方法。这个方法可能让你更难去不指定某些列。SQLAlchemy的声明基础已经为你提供了一个默认的__init__方法,它已经能满足你的需求,并且还能保留默认值。

如果你不想完全去掉__init__,你可以修改这个__init__方法,让它默认值为None,或者像Burhan的回答那样,明确指定列的值为None

class Users(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)
    password = Column(String)
    email = Column(String)

    def __init__(self, name=None, password=None, email=None):
        self.name = name
        self.password = password
        self.email = email

然后使用session.add(Users())来插入一行“完全空”的数据(如果你完全去掉__init__,这也能正常工作)。

0

因为你正在使用一个叫做声明式基础的东西,所以你可以直接这样做:

u = Users('foo',None,None)
session.add(u)
session.commit()

撰写回答