我想在SQL数据库的额外表中存储对通用目的的数据库条目的引用。
我在SQLAlchemy中的数据模型如下所示:
class Entity(db.Model):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(10))
def __init__(self, name):
self.name = name
class Entry(db.Model):
id = db.Column(db.Integer, primary_key=True)
name= db.Column(db.String(10))
entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'))
def __init__(self, name, entity_id):
self.name = name
self.entity_id = entity_id
class Thing(db.Model):
id = db.Column(db.Integer, primary_key=True)
name= db.Column(db.String(10))
entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'))
def __init__(self, name, entity_id):
self.name = name
self.entity_id = entity_id
只要创建了条目或 Thing , entity_id 中就会有一个对实体即可。为了解决这个问题,我首先创建一个实体,提交它,然后从新创建的实体中获取id,并使用抓取的id创建条目或 Thing 。
# Create a new Entity object
entity = Entity(entity_title)
# Commit the entity
db.session.add(entity)
db.session.commit()
# Get the entity ID
entity_id = Entity.query.filter_by(name=entity_title).first().id
# Create a new Entry/Thing object
entry= Entry(name, entity_id)
# Commit the entry
db.session.add(task)
db.session.commit()
这种方式看起来效率很低。还有其他方法可以解决这个问题吗?
答案 0 :(得分:1)
relationships不是手动处理外键,而是提供这样一个目的,即允许您处理对象及其关系的内存表示,而无需按正确顺序执行flush()
es找出你应该放在哪里的外键。
class Entry(db.Model):
id = db.Column(db.Integer, primary_key=True)
name= db.Column(db.String(10))
entity_id = db.Column(db.Integer, db.ForeignKey('entity.id'))
entity = relationship(Entity)
entry = Entry(name="foo", entity=Entry(name="foo"))
db.session.add(entry)
db.session.commit()
请注意您根本不必处理entity_id
在您的特定情况下,您可能还会发现inheritance有用:
class Entity(db.Model):
__tablename__ = "entities"
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(10))
type = db.Column(db.Enum("entry", "thing"))
def __init__(self, name):
self.name = name
__mapper_args__ = {
"polymorphic_on": type,
}
class Entry(Entity):
__tablename__ = "entries"
id = db.Column(db.Integer, db.ForeignKey('entity.id') primary_key=True)
class Thing(Entity):
__tablename__ = "things"
id = db.Column(db.Integer, db.ForeignKey('entity.id') primary_key=True)
entry = Entry(name="foo") # automatically deals with the entities table
db.session.add(entry)
db.session.commit()
答案 1 :(得分:0)
您可以使用session.flush()
entity = Entity(entity_title)
# Commit the entity
db.session.add(entity)
db.session.flush()
之后你可能在entity.id
中有id
session.flush()
仅“创建”一个实例,但它实际上没有提交您的会话
在你的情况下
# Create a new Entity object
entity = Entity(entity_title)
# Commit the entity
db.session.add(entity)
db.session.flush()
# Didn't need
# Get the entity ID
# entity_id = Entity.query.filter_by(name=entity_title).first().id
# Create a new Entry/Thing object
entry= Entry(name, entity.id)
# Commit the entry
db.session.add(task)
db.session.commit()
这里是文档 http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.flush