如何在SQLAlchemy或SqlSoup ORM中自动反映表关系?

发布于 2024-11-25 22:32:11 字数 608 浏览 3 评论 0原文

如何告诉 SQLAlchemy 自动将基本外键引用反映为对其他 ORM 对象而不是整数字段的引用?

SQLAlchemy 中,它是 SQLAlchemy。 sqlalchemy.org/docs/orm/extensions/sqlsoup.html#relationships">SqlSoup,表列会自动反映,关系可以手动定义:

class User(Base):
    __table__ = metadata.tables['users']
    loan = relation(Loans)

...

You can define relationships on SqlSoup classes:
>>> db.users.relate('loans', db.loans)

How do I tell SQLAlchemy to automatically reflect basic Foreign Key references as references to other ORM objects and not integer fields?

In both SQLAlchemy and it's SqlSoup, table columns are reflected automatically and relations can be defined manually:

class User(Base):
    __table__ = metadata.tables['users']
    loan = relation(Loans)

...

You can define relationships on SqlSoup classes:
>>> db.users.relate('loans', db.loans)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

糖粟与秋泊 2024-12-02 22:32:11

试试这个魔法)
适用于简单的 FK 关系,并且没有数据库方案

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import mapper, relation

engine = create_engine("sqlite://", echo=True)

engine.execute('''
    create table foo (
        id integer not null primary key,
        x integer
    )''')

engine.execute('''
    create table bar (
        id integer not null primary key,
        foo_id integer,
        FOREIGN KEY(foo_id) REFERENCES foo(id)
    )''')

metadata = MetaData()
metadata.reflect(bind=engine)


MAPPERS = {
}

repr_name = lambda t: '%s%s' % (t[0].upper(), t[1:])

for table in metadata.tables:

    cls = None
    # 1. create class object
    cls_name = repr_name(str(table))
    exec("""class %s(object): pass""" % cls_name)
    exec("""cls = %s""" % cls_name)

    # 2. collect relations by FK
    properties = {}
    for c in metadata.tables[table].columns:
        for fk in c.foreign_keys:
            name = str(fk.column).split('.')[0]
            properties.update({
                name: relation(lambda: MAPPERS[repr_name(name)]),
            })

    # 3. map table to class object 
    mapper(cls, metadata.tables[table], properties=properties)


    MAPPERS.update({cls_name: cls})

if __name__ == '__main__':
    from sqlalchemy.orm import sessionmaker

    print 'Mappers: '
    for m in MAPPERS.values():
        print m

    session = sessionmaker(bind=engine)()

    foo = Foo()
    foo.x = 1
    session.add(foo)

    session.commit()

    print session.query(Foo).all()

    bar = Bar()
    bar.foo = foo
    session.add(bar)
    session.commit()

    print session.query(Bar).all()

Try this magic )
Works for simple FK relations, and without db schemes

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import mapper, relation

engine = create_engine("sqlite://", echo=True)

engine.execute('''
    create table foo (
        id integer not null primary key,
        x integer
    )''')

engine.execute('''
    create table bar (
        id integer not null primary key,
        foo_id integer,
        FOREIGN KEY(foo_id) REFERENCES foo(id)
    )''')

metadata = MetaData()
metadata.reflect(bind=engine)


MAPPERS = {
}

repr_name = lambda t: '%s%s' % (t[0].upper(), t[1:])

for table in metadata.tables:

    cls = None
    # 1. create class object
    cls_name = repr_name(str(table))
    exec("""class %s(object): pass""" % cls_name)
    exec("""cls = %s""" % cls_name)

    # 2. collect relations by FK
    properties = {}
    for c in metadata.tables[table].columns:
        for fk in c.foreign_keys:
            name = str(fk.column).split('.')[0]
            properties.update({
                name: relation(lambda: MAPPERS[repr_name(name)]),
            })

    # 3. map table to class object 
    mapper(cls, metadata.tables[table], properties=properties)


    MAPPERS.update({cls_name: cls})

if __name__ == '__main__':
    from sqlalchemy.orm import sessionmaker

    print 'Mappers: '
    for m in MAPPERS.values():
        print m

    session = sessionmaker(bind=engine)()

    foo = Foo()
    foo.x = 1
    session.add(foo)

    session.commit()

    print session.query(Foo).all()

    bar = Bar()
    bar.foo = foo
    session.add(bar)
    session.commit()

    print session.query(Bar).all()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文