2014-10-01 52 views
2

这可能是一个挑战,但我试图找到一个很好的方式来获得整个数据库“外观”的总体思路。下面是使用Flask-SQLAlchemy,少数机型有不同的关系和属性(当然,大部分刚刚从SQLAlchemy的文档拍摄)将SQLAlchemy数据库打印为模型和关系的好方法是什么?

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']) 

回答

3

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

Base.__subclasses__() 

然后,为了获取列的列表对特定的模式,例如User,你可以看看映射器:

User.__mapper__.attrs 

每个那些可以是ColumnPropertyRelationshipProperty。对于ColumnProperty,你可以得到Column对象(它实际上的Column秒的名单,但我认为这是很少有不止一个):

prop.columns[0] 

Column对象你定义的所有信息时,您声明了该模型,包括它是主键(c.primary_key)还是外键(c.foreign_keys)。

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

全部放在一起:

for model in Base.__subclasses__(): 
    print "<model {}>".format(model.__name__) 
    for a in model.__mapper__.attrs: 
     if isinstance(a, ColumnProperty): 
      c = a.columns[0] 
      line = a.key 
      if c.primary_key: 
       line += " (primary key)" 
      if c.foreign_keys: 
       line += " -> " + ", ".join([fk.target_fullname for fk in c.foreign_keys]) 
      print line 
     elif isinstance(a, RelationshipProperty): 
      print "{} -> {} relationship with <model {}>".format(
       a.key, a.direction.name, a.mapper.class_.__name__) 
    print "" 
+0

不错!谢谢你,先生 – corvid 2014-10-01 18:58:25

相关问题