[英]SQLAlchemy autoload insert record
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
包含一个带有命名参数的构造函数。 该construtor的代码如下(从github存储库逐字):
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列。
你能用这样的方法:
class TableObject(Base):
def __init__(self, name, sex, age):
super(TableObject, self).__init__()
self.name = name
self.sex = sex
self.age = age
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.