我正在使用alchimia异步使用SQLAlchemy的强大功能。
我遇到的唯一问题是从原始查询构建对象变得单调乏味,有没有一种方法可以使用ORM的SQLAlchemy 构建对象而不实际使用ORM本身?
例如,假设我在alchimia dox示例中有一个user
表:
users = Table("users", metadata,
Column("id", Integer(), primary_key=True),
Column("name", String()),
)
我查询它以检索所有用户:
result = yield engine.execute(users.select())
我想返回模型实例而不是dict
,所以我创建了一个简单的构建器:
class BaseModel(object, pythonutil.FancyEqMixin,
pb.Copyable, pb.RemoteCopy):
compareAttributes = ('id',)
tbl = None
def __init__(self, *args, **kwargs):
for arg in args:
if isinstance(arg, dict):
for k, v in arg.items():
setattr(self, k, v)
if kwargs:
for k, v in kwargs.items():
setattr(self, k, v)
@classmethod
def build(cls, resource, alias=None):
assert (isinstance(cls.tbl, sa.Table)), \
"Model's '.tbl' property must be a sqlalchemy.schema.Table"
if isinstance(resource, tuple):
resource = resource[0]
resource = dict(resource)
if alias is not None:
from sqlalchemy.sql import expression
alias = (alias.name if
isinstance(alias, expression.Alias)
else str(alias))
else:
alias = cls.tbl.name
rawdata = dict()
for (k, v) in resource.items():
if not k.startswith(alias):
continue
# remove the alias from the columns name, some tables
# may have underscores in their name, so count the occurrence
# of "_" i the alias ( = tablename) and get the string after it
# e.g. "module_server_module_ipaddr" becomes "module_ipaddr"
_k = '_'.join(k.split('_')[1 + alias.count('_'):])
try:
# try to get the column from table, on fail skip
cls.tbl.c[_k]
except KeyError:
continue
rawdata[_k] = v
return cls(**rawdata)
def update(self, other):
assert isinstance(other, BaseModel), \
"other should be %r, %r given" % (BaseModel, other)
for k, v in other.__dict__.items():
setattr(self, k, v)
def __setitem__(self, key, value):
return setattr(self, key, value)
def __getitem__(self, item):
return getattr(self, item)
此对象的工作方式类似于字典,但可以使用原始查询数据构建,这里是模型示例:
class User(BaseModel):
tbl = user_tbl
我可以定义像SQLAlchemy ORM那样的模型,使用sqlalchemy core
查询数据库,然后使用查询数据构建模型吗?