V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
yakczh
V2EX  ›  问与答

sqlalchemy 能通过 dict 添加纪录吗?

  •  
  •   yakczh · 2015-01-01 13:19:54 +08:00 · 3621 次点击
    这是一个创建于 3643 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如文章表的字段有标题,作者,内容,发布时间,发布状态 ,但是其中发布时间,发布状态是有默认值的
    如果用
    session.add( User('tittle','autrho','content','2015-01-01',0') ) 这种方式必须每个值都得写上,如果数据库表增加了字段,又要修改代码

    如果用diCt只传必要的数据,我试了下
    data={"title":"xxxx","author":"oooo","content":"ksjfosjfos"}

    session.add(Article(data))
    提示
    TypeError: __init__() takes exactly 1 argument (2 given)

    这个新增的字段必须写死吗? 能不能实现只传必须的字段?
    5 条回复    2015-01-01 18:31:17 +08:00
    Cynic222
        1
    Cynic222  
       2015-01-01 13:34:38 +08:00
    没试过,但我猜可以session.add(Article(**data))
    timonwong
        2
    timonwong  
       2015-01-01 13:36:21 +08:00
    http://docs.sqlalchemy.org/en/rel_0_9/orm/tutorial.html#create-an-instance-of-the-mapped-class
    如果你没有自定义 __init__ 方法,那么SQLAlchemy已经提供了一个keyword arguments的调用方法,你的代码就只需要:
    Article(**data) 就可以了

    但是如果你自定义了__init__ 就不行了,要写个包装函数,比如from_dict

    PS, 这个是默认 __init__ 的实现:

    ```
    def _declarative_constructor(self, **kwargs):
    """A simple constructor that allows initialization from kwargs.

    Sets attributes on the constructed instance using the names and
    values in ``kwargs``.

    Only keys that are present as
    attributes of the instance's class are allowed. These could be,
    for example, any mapped columns or relationships.
    """
    cls_ = type(self)
    for k in kwargs:
    if not hasattr(cls_, k):
    raise TypeError(
    "%r is an invalid keyword argument for %s" %
    (k, cls_.__name__))
    setattr(self, k, kwargs[k])
    _declarative_constructor.__name__ = '__init__'
    ```
    yakczh
        4
    yakczh  
    OP
       2015-01-01 17:46:40 +08:00
    @timonwong

    articles_table = Table('articles',metadata,
    Column('id',Integer,primary_key=True),
    Column('title',String(40)),
    Column('author',String(40)),
    Column('content',String(40)),
    Column('ctime',Integer,default=0),
    Column('status',Integer,default=0),


    )
    class Article(object):
    >>def __repr__(self):

    >>>>return "<Article('%s','%s','%s')>" % (self.title,self.author,self.content)
    mapper(Article,articles_table)
    data={"title":"xxxx","author":"oooo","content":"ksjfosjfos"}
    u=Article(**data)
    session.add(u)

    运行提示:
    u=Article(**data)
    TypeError: __init__() got an unexpected keyword argument 'content'


    很奇怪不报 title,author出错
    timonwong
        5
    timonwong  
       2015-01-01 18:31:17 +08:00
    @yakczh
    你用的是classic 的mapper,自然用不了 declarative mapper 的方法

    declarative mapper 会自然的把 default constructor 给实现一次,classic 的就需要自行手动实现。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2414 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:25 · PVG 08:25 · LAX 16:25 · JFK 19:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.