什么是将SQLAlchemy数据库打印为模型和关系的好方法?

时间:2014-10-01 17:47:22

标签: python flask sqlalchemy

这可能是一个挑战,但我试图找到一个很好的方法来获得我的整个数据库“看起来”的总体思路。这是一个使用Flask-SQLAlchemy的小例子,一些具有不同关系和属性的模型(诚然,大多数只是从SQLAlchemy Docs中获取)

class IDModel(db.Model):
  __abstract__ = True
  id = db.Column(db.Integer, primary_key=True)

class User(db.Model, IDModel):
  __tablename__ = 'users'
  username = db.Column(db.String(64), unique=True)
  _roles = db.relationship(
    Role, lambda: user_role, collection_class=set,
    backref=db.backref('users', collection_class=set)
  )
  roles = association_proxy('_roles', 'name')

# One-to-many
class Post(db.Model, IDModel):
  __tablename__ = 'posts'
  html = db.Column(db.Text)
  author_id = db.Column(db.Integer, backref="users.id")
  author = db.relationship("User")

# Many-to-Many
class Role(db.Model, IDModel):
  __tablename__ = 'roles'
  name = db.Column(db.String)

user_role = db.Table(
  'user_role',
  db.Column('user_id', db.Integer, db.ForeignKey(User.id), primary_key=True),
  db.Column('role_id', db.Integer, db.ForeignKey(Role.id), primary_key=True)
)

理想情况下,我想要做的是更改我的数据库的__repr__,以便为给定的数据库打印如下内容:

<Model 'User'>
id (primary key)
username
roles -> MANY-TO-MANY relationship with <Model 'Roles'>

<Model 'Post'>
id (primary_key)
html
author_id -> 'User.id'
author -> ONE-TO-MANY relationship with <Model 'User'>

<Model 'Role'>
id (primary key)
name
MANY TO MANY relationship with <Model 'User'>

这样的事情可能吗?

添加我的贡献,我能够打印所有表及其列,但是很难打印关系并删除关系表。

>>> from app import db
>>> inspector = db.inspect(db.engine)
>>> for table in inspector.get_table_names():
        print("<Model '{}'".format(table))
        for column in inspector.get_columns(table):
            print(column['name'])

2 个答案:

答案 0 :(得分:4)

您不需要反映数据库来执行此操作;你可以检查每个模型。获取从Base继承的所有模型的列表:

Base.__subclasses__()

然后,获取特定模型的列列表,例如User,您可以查看映射器:

User.__mapper__.attrs

每个都可以是ColumnPropertyRelationshipProperty。对于ColumnProperty,您可以获取Column对象(它实际上是Column的列表,但我认为拥有多个对象很少见) :

prop.columns[0]

Column对象包含您在声明模型时定义的所有信息,包括它是主键(c.primary_key)还是外键({{1 }})。

对于c.foreign_keys,您可以使用RelationshipProperty获取远程端的映射器。要获得课程,您可以c.mapper。您还可以使用c.mapper.class_找到方向。

全部放在一起:

c.direction

答案 1 :(得分:1)

目前,存在两种解决方案:

  1. https://github.com/manicmaniac/sqlalchemy-repr - 很酷,但打印所有可能导致巨大repr的属性。
  2. https://github.com/absent1706/sqlalchemy-mixins#beauty-repr - 受第一个启发;允许您指定要在repr中查看的属性。