我有一个已经具有以下表的现有数据库数据集: 具有ownerid为primary_key的所有者表
另一个表owndnis,其primary_key是相同的ownerid
另一个表,其primary_key与所有者的所有者ID相同
我想定义一个看起来像这样的关系
所有者 有 {owndnis}和 {application_parameters}
我的模型和路线文件的内容在下面给出
model.py
from marshmallow import fields
from flask import jsonify
class owners(db.Model):
__tablename__ = 'owners'
ownerid = db.Column('ownerid',db.String(60), nullable=False)
name = db.Column('ownerdomainname', db.String(60),primary_key=True, nullable=False)
spownerid = db.Column('spownerid', db.String(60))
ownerid = db.Column(db.String(), db.ForeignKey('owndnis.ownerid'))
dnis = db.relationship("owndnis", uselist=False, backref="owners")
# ownerid = db.Column(db.String(), db.ForeignKey('application_parameters.ownerid'))
# app_params = db.relationship("application_parameters", backref="owners")
class owndnis(db.Model):
__tablename__ = 'owndnis'
ownerid = db.Column('ownerid',db.String(60),primary_key=True)
dnisstart = db.Column('dnisstart', db.String(20), nullable=False)
dnisend = db.Column('dnisend', db.String(20))
class application_parameters(db.Model):
__tablename__ = 'application_parameters'
ownerid = db.Column('ownerid',db.String(60),primary_key=True)
applicationid = db.Column('applicationid', db.String(60), nullable=False)
key = db.Column('key', db.String(128), nullable=False)
value = db.Column('value', db.String(1024), nullable=False)
###### SCHEMAS #####
class owndnis_schema(ma.ModelSchema):
dnisstart = fields.String()
dnisend = fields.String()
class app_params_schema(ma.ModelSchema):
key = fields.String()
value = fields.String()
class owners_schema(ma.ModelSchema):
ownerid = fields.String()
ownerdomainname = fields.String()
spownerid = fields.String()
ownerdescription = fields.String()
dnis = fields.Nested(owndnis_schema)
app_params = fields.Nested(app_params_schema)
routes.py
---------
from model import owners, owndnis, application_parameters,owners_schema,owndnis_schema, app_params_schema
@mod.route('/api/sp/<spdomainname>', methods=['GET'])
def findSp(spdomainname):
ownerArr = []
owner = owners.query.get(spdomainname)
owner_schema = owners_schema()
if owner:
owners_sm_result = owner_schema.dump(owner).data
return jsonify({'owner': owners_sm_result})
I get the output like this
{
"owner": {
"spownerid": "SYSTEM",
"ownerid": "NEWSP~ZryOZB9BGb",
"dnis": {
"dnisend": "199999",
"dnisstart": "100000"
}
}
}
If I uncomment the commented lines in model.py(owners) to include another table that has foreign key same as owndnis table
but I get this run time error
File "/home/holly/python_ws/new_project_blue/blue/lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line 2383, in _determine_joins
"specify a 'primaryjoin' expression." % self.prop
sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship owners.dnis - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
[pid: 18308|app: 0|req: 1/1] 10.133.0.31 () {34 vars in 620 bytes} [Tue May 14 07:22:14 2019] GET /api/sp/NEW-SP => generated 0 bytes in 25 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)
The requirement is to have the output like this
I get the output like this
{
"owner": {
"spownerid": "SYSTEM",
"ownerid": "NEWSP~ZryOZB9BGb",
"dnis": {
"dnisend": "199999",
"dnisstart": "100000"
},
"app_params": {
"key":"xxxxx",
"value":"yyyy"
}
}
}
答案 0 :(得分:0)
我将严格遵循文档中的关系模式:
https://docs.sqlalchemy.org/en/13/orm/basic_relationships.html
作为示例,假设您希望在owners
和owndnis
之间建立一对一的关系...
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
child = relationship("Child", uselist=False, back_populates="parent")
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
parent = relationship("Parent", back_populates="child")
未经测试,但遵循此模式,在您的情况下,将owners
作为父项:
# Treated as Parent of One to One
class owners(db.Model):
__tablename__ = 'owners'
ownerid = db.Column('ownerid', db.String(60), primary_key=True) <--- changed primary key
name = db.Column('ownerdomainname', db.String(60), nullable=False)
spownerid = db.Column('spownerid', db.String(60))
dnis = db.relationship("owndnis", uselist=False, back_populates="owners") <--- note change
# child = relationship("Child", uselist=False, back_populates="parent")
# Treated as Child of One to One
class owndnis(db.Model):
__tablename__ = 'owndnis'
ownerid = db.Column('ownerid', db.String(60),
primary_key=True, db.ForeignKey('owners.ownerid')) <-- both a PK and FK
dnisstart = db.Column('dnisstart', db.String(20), nullable=False)
dnisend = db.Column('dnisend', db.String(20))
owner = relationship("owners", back_populates="owndnis") <--- added
# parent = relationship("Parent", back_populates="child")
我使用过back_populates
,但根据文档:
和往常一样,可以使用Relationship.backref和backref()函数来代替Relationship.back_populates方法;要在backref上指定uselist,请使用backref()函数:
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
child_id = Column(Integer, ForeignKey('child.id'))
child = relationship("Child", backref=backref("parent", uselist=False))