2014-10-01 24 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

相關問題