用MetaData描述数据库

这节讨论基本的Table,Column,MetaData对象。

from sqlalchemy import *
metadata = MetaData()

MetaData 是一个容器对象,包含了许多描述数据库的特征。

可以用Table 类来描绘一个表,它的前两个参数是表名和关联的MetaData对象。剩下的参数大部分是Column 对象用来描述列。

user = Table('user', metadata,
    Column('user_id', Integer, primary_key = True),
    Column('user_name', String(16), nullable = False),
    Column('email_address', String(60)),
    Column('password', String(20), nullable = False))

上面的例子中,一个user表就被描述了。如果要描述复合主键,可以在多个列后面加上primary_key = True。


访问表和列

metadata 包含所有关联过它的schema的结构。它有一些方法去访问这些表对象的属性,比如sorted_tables 属性可以返回所有关联的表对象,按照外键关联排序(每个表对象优先于它关联的任何其他表)

>>> for t in metadata.sorted_tables:...    
            print t.name
 user
 user_preference
 invoice
 invoice_item


下面来举例说明表定义和属性的访问

employees = Table('employees', metadata,
    Column('employee_id', Integer, primary_key=True),
    Column('employee_name', String(60), nullable=False),
    Column('employee_dept', Integer, ForeignKey("departments.department_id"))
)

可访问的属性如下:

# access the column "EMPLOYEE_ID":
employees.columns.employee_id

# or just
employees.c.employee_id

# via string
employees.c['employee_id']

# iterate through all columns
for c in employees.c:
    print c

# get the table's primary key columns
for primary_key in employees.primary_key:
    print primary_key
    
# get the table's foreign key objects:
for fkey in employees.foreign_keys:
    print fkey

# access the table's MetaData:
employees.metadata

# access the table's bound Engine or Connection, if its MetaData is bound:
employees.bind

# access a column's name, type, nullable, primary key, foreign key
employees.c.employee_id.name
employees.c.employee_id.type
employees.c.employee_id.nullable
employees.c.employee_id.primary_key
employees.c.employee_dept.foreign_keys

# get the "key" of a column, which defaults to its name, but can
# be any user-defined string:
employees.c.employee_name.key

# access a column's table:
employees.c.employee_id.table is employees

# get the table related by a foreign key
list(employees.c.employee_dept.foreign_keys)[0].column.table

创建和删除数据库表

通常的创建表的方法是在MetaData对象上用create_all()方法。这个方法会先检查是否存在该表,不存在则创建。

 engine = create_engine('sqlite:///:memory:')
 
 metadata = MetaData()
 
 user = Table('user', metadata,
        Column('user_id', Integer, primary_key = True),
        Column('user_name', String(16), nullable = False),
        Column('email_address', String(60), key='email'),
        Column('password', String(20), nullable = False)
    )
    user_prefs = Table('user_prefs', metadata,
        Column('pref_id', Integer, primary_key=True),
        Column('user_id', Integer, ForeignKey("user.user_id"), nullable=False),
        Column('pref_name', String(40), nullable=False),
        Column('pref_value', String(100))
    )
    
    metadata.create_all(engine)

create_all()方法创建外键关联通常是与创建表的同时,所以它会按照依赖关系来创建表。也有方法来改变这种行为,比如later table 就可以。


删除多有表一般用drop_all()方法。这个方法和create_all()正好相反,先检查依赖关系,然后按照相反的顺序来删除表。


创建和删除单个的表可以用create()和drop()方法。

    engine = create_engine('sqlite:///:memory:')
    meta = MetaData()
    employees = Table('employees', meta,
        Column('employee_id', Integer, primary_key=True),
        Column('employee_name', String(60), nullable=False, key='name'),
        Column('employee_dept', Integer, ForeignKey("departments.department_id"))
    )
    employees.create(engine)
    employees.drop(engine)

如果要开启'检查表是否存在'这个逻辑,可以用checkfirst = True参数

employees.create(engine, checkfirst=True)
employees.drop(engine, checkfirst=False)

指定后端(数据库引擎)

addresses = Table('engine_email_addresses', meta,
    Column('address_id', Integer, primary_key = True),
    Column('remote_user_id', Integer, ForeignKey(users.c.user_id)),
    Column('email_address', String(20)),
 mysql_engine='InnoDB')


列/表/MetaData 的API接口不再翻译,请自行查阅

http://docs.sqlalchemy.org/en/latest/core/metadata.html