PostgreSQL 有学生表:
Table "public.student"
Column | Type | Modifiers
--------+-----------------------+------------------------------------------------------
id | integer | not null default nextval('student_id_seq'::regclass)
name | character varying(10) |
sex | character varying(6) |
age | integer |
Indexes:
"student_pkey" PRIMARY KEY, btree (id)
我可以这样插入一条记录:
Base = declarative_base()
class TableObject(Base):
__table__ = Table('student', metadata, autoload=True)
record = TableObject(name="tom", sex="male")
session.add(record)
record = TableObject(name="alice", sex="female", age=10)
session.add(record)
我希望有这样一种方法:
record = TableObject("alice", "female", 10)
session.add(record)
导致错误
TypeError: __init__() takes exactly 1 argument (4 given)
因为我会从一个文件中获取记录,并将每一行拆分成列表,所以如果支持这种方法,那将是非常方便的。
有什么办法吗?
最佳答案
您现在可以插入记录,因为 declarative_base
包含一个采用命名参数的构造函数。该构造函数的代码如下(来自 github repository 的逐字记录):
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__'
因此,如果您想用位置版本替换此构造函数,那么它将适用于您的所有模型。以下可能是一个起点:
def _declarative_positional_constructor(self, *args, **kwargs):
assert len(kwargs) == 0
column_names = tuple(c.name for c in self.__mapper__.columns if not(c in self.__mapper__.primary_key))
assert len(column_names) == len(args)
for name, value in zip(column_names, args):
setattr(self, name, value)
_declarative_positional_constructor.__name__ = '__init__'
# ...
# use own default constructor
Base = declarative_base(constructor = _declarative_positional_constructor)
然而,在这种情况下,使用名称创建实例的方法将不起作用。因此,您可以增强它以处理两个版本。
另一件要检查的事情是 autoload
保证表中列的顺序相同,以防止在将“John”写入 Gender 时将“male”存储为名称专栏。
关于python - SQLAlchemy 自动加载插入记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20370424/