【问题标题】:sqlalchemy foreign keys / query joinssqlalchemy 外键/查询连接
【发布时间】:2012-05-15 11:01:21
【问题描述】:

您好,我在 sqlalchemy 中的外键有一些问题,不能在主键 ID 上自动递增

我正在使用:python 2.7、金字塔 1.3 和 sqlalchemy 0.7

这是我的模型

class Page(Base):
    __tablename__ = 'page'
    id = Column(Integer, ForeignKey('mapper.object_id'), autoincrement=True, primary_key=True)
    title = Column(String(30), unique=True)
    title_slug = Column(String(75), unique=True)
    text = Column(Text)
    date_added = Column(DateTime)

class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    name = Column(String(100), unique=True)
    email = Column(String(100), unique=True)
    password = Column(String(100))

class Group(Base):
    __tablename__ = 'groups'
    id = Column(Integer, primary_key=True)
    name = Column(String(100), unique=True)

class Member(Base):
    __tablename__ = 'members'

    user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
    group_id = Column(Integer, ForeignKey('groups.id'), primary_key=True)

class Resource(Base):
    __tablename__ = 'resource'

    id = Column(Integer, primary_key=True)
    tablename = Column(Text)
    action = Column(Text)

class Mapper(Base):
    __tablename__ = 'mapper'

    resource_id = Column(Integer, ForeignKey('resource.id'), primary_key=True)
    group_id = Column(Integer, ForeignKey('groups.id'), primary_key=True)
    object_id = Column(Integer, primary_key=True)

这是我用 SQLAlchemys ORM 编写的 RAW SQL 查询

'''
SELECT g.name, r.action
FROM groups AS g
INNER JOIN resource AS r
ON m.resource_id = r.id
INNER JOIN page AS p
ON p.id = m.object_id
INNER JOIN mapper AS m
ON m.group_id = g.id
WHERE p.id = ? AND
r.tablename = ?;
'''
obj = Page
query = DBSession().query(Group.name, Resource.action)\
        .join(Mapper)\
        .join(obj)\
        .join(Resource)\
        .filter(obj.id == obj_id, Resource.tablename == obj.__tablename__).all()

原始 SQL Query 工作正常,Page 和 Mapper 之间没有任何关系,但 SQLAlchemys ORM 似乎需要 ForeignKey 链接才能加入它们。所以我决定把 ForeignKey 放在 Page.id 因为 Mapper.object_id 会链接到几个不同的表。

这使得带有连接的 SQL ORM 查询按预期工作,但将新数据添加到 Page 表会导致异常。

FlushError: Instance <Page at 0x3377c90> has a NULL identity key.  
If this is an auto-  generated value, check that the database 
table allows generation of new primary key values, and that the mapped 
Column object is configured to expect these generated values.  
Ensure also that this flush() is not occurring at an inappropriate time, 
such as within a load() event.

这是我的视图代码:

try:
    session = DBSession()
    with transaction.manager:
        page = Page(title, text)
        session.add(page)
        return HTTPFound(location=request.route_url('home'))
except Exception as e:
    print e
    pass
finally:
    session.close()

我真的不知道为什么,但我宁愿使用 SQLalchemy 中的解决方案,也不愿使用 RAW SQL,因为我制作这个项目是为了学习目的 :)

【问题讨论】:

    标签: python orm sqlalchemy pyramid


    【解决方案1】:

    我不认为autoincrement=TrueForeignKey(...) 一起玩得很好。

    无论如何,要让join 在没有任何ForeignKey 的情况下工作,您只需在join(...) 的第二个参数中指定join 条件即可:

    obj = Page
    query = DBSession().query(Group.name, Resource.action)\
        .join(Mapper)\
        .join(Resource)\
        .join(obj, Resource.tablename == obj.__tablename__)\
        .filter(obj.id == obj_id)\
        .all()
    

    【讨论】:

    • 是的,当我第一次开始获取 null FlushError 时,我刚刚添加了 autoincrement=True。当我回到家时会尝试这个并根据结果接受/询问更多问题:)但是谢谢!
    猜你喜欢
    • 2018-06-18
    • 1970-01-01
    • 2017-08-28
    • 2016-05-08
    • 1970-01-01
    • 2014-04-21
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    相关资源
    最近更新 更多