来自C#/ EF世界的Python和SQLAlchemy的新手;尝试在后者中做一些非常简单的事情,所以我认为至少在前者中必须做到这一点。
问题:从JSON数据加载表,但是表由具有自引用层次结构的对象定义,例如:
class TableMixin(object):
def __init__(self, jsonData = None):
if(jsonData is not None):
self.__dict__ = json.loads(jsonData)
@declared_attr
def __tablename__(self):
return self.__name__
id = Column(Integer, primary_key = True)
class HierarchyMixin(object):
@declared_attr
def predecessor_id(self):
return Column(Integer, ForeignKey(self.__name__ + '.id'))
@declared_attr
def successors(self):
return relationship(self.__name__)
class Something(TableMixin, HierarchyMixin, Base):
a_property = Column(String)
b_property = Column(String)
然后我有一些JSON数据,例如:
{
"a_property":"some value",
"b_property":"some other value",
"successors":[
{
"a_property":"some value 1",
"b_property":"some other value 1"
},
{
"a_property":"some value 2",
"b_property":"some other value 2"
"successors":[
{
"a_property":"some value 3",
"b_property":"some other value 3"
}
}
]
}
我的目标是将其加载到数据库中。为此,我有:
import json
from MyEntities import Something
from sqlalchemy import Table, MetaData, Column, Integer, String, ForeignKey, create_engine
from sqlalchemy.orm import mapper, sessionmaker
db_engine = create_engine('sqlite:///my.db', echo=True)
db_conn = db_engine.connect()
Session = sessionmaker(bind = db_engine)
db_sesn = Session()
with open('MyJsonData.json', encoding='utf-8-sig') as json_data_file:
data = Something(json_data_file.read())
db_sesn.add(data)
db_sesn.commit()
它不起作用。我得到:
sqlalchemy.orm.exc.UnmappedInstanceError: Class 'Entities.Something' is mapped, but this instance lacks instrumentation. This occurs when the instance is created before sqlalchemy.orm.mapper(Entities.Something) was called.
我四处寻找,发现一切似乎都还可以,因为所有数据都将被加载,创建以及对象层次结构。创建后,我可以通过访问该“数据”对象的各个成员进行确认。当我尝试将其添加到数据库时出现错误。
据我所知,这不应该超出我对SQLAlchemy的处理范围。但是对于我的一生,我找不到适合我的案例的具体例子。
我会要求您原谅一些可能是“非pythonic”的工作模式的时间-我还在学习:-)
答案 0 :(得分:0)
我认为这只是我对Python和SqlAlchemy的新颖性,阻止了我立即看到解决方案,这实际上很简单。
在我最初的代码示例中,我做到了:
class HierarchyMixin(object):
def __init__(self, data = None):
if data is not None:
if 'successors' in data:
self.successors = list(map(self.__class__, data['successors']))
if 'a_property' in data:
self.a_property = data['a_property']
if 'b_property' in data:
self.b_property = data['b_property']
@declared_attr
def predecessor_id(self):
return Column(Integer, ForeignKey(self.__name__ + '.id'))
@declared_attr
def successors(self):
return relationship(self.__name__)
a_property = Column(String)
b_property = Column(String)
class Something(TableMixin, HierarchyMixin, Base):
pass
我在那里所做的全部工作就是为successors
属性分配一个列表,该列表将每个成员映射到该类的新实例。而且...嗯,差不多了。
然后,使用Json数据文件,我只是:
with open('MyJsonData.json', encoding = 'utf-8-sig') as json_data:
not_nothing = Something(json.loads(json_data.read()))
仅此而已。分层数据结构作为关系导入,并正确设置了所有predecessor_id键。
我只是因为没有立即看到这么明显的简单事情而对自己感到恼火,但是我想将其归结为学习一种新语言而不是完全 getting Python。快速变化:-)