使用 SQLAlchemy 基于类自动构建数据库表
Posted
技术标签:
【中文标题】使用 SQLAlchemy 基于类自动构建数据库表【英文标题】:Automatically Build Database Table based on a Class with SQLAlchemy 【发布时间】:2013-05-15 21:18:57 【问题描述】:我真的是 SQLAlchemy 的新手,我喜欢它。现在我手动做很多事情,我想做更多“python”和动态的事情。
举个例子,我有一个简短的脚本,可以手动创建/定义一个表,然后是一个将数据插入该表的函数。
数据库连接
import os
from sqlalchemy import *
from sqlalchemy import schema, types
from sqlalchemy.ext.declarative import declarative_base
db_url = os.environ.get('DATABASE_URL')
engine = create_engine(db_url)
Base = declarative_base(engine)
meta = Base.metadata
表定义
file_paths = Table('file_paths', meta,
Column('table_id', Integer, primary_key = True),
Column('fullpath', String(255)),
Column('filename', String(255)),
Column('extension', String(255)),
Column('created', String(255)),
Column('modified', String(255)),
Column('size', Integer),
Column('owner', String(255)),
Column('permissions', Integer),
mysql_engine='InnoDB',
)
file_paths.drop(engine, checkfirst = False)
file_paths.create(engine, checkfirst = True)
插入函数接受一个字符串和一个列表作为参数
def push_to_db(fullpath, fileInfo):
i = file_paths.insert()
i.execute( fullpath = str(fullpath),
filename = str(fileInfo[0]),
extension = str(fileInfo[1]),
created = str(fileInfo[2]),
modified = str(fileInfo[3]),
size = str(fileInfo[4]),
owner = str(fileInfo[5]),
permissions = str(fileInfo[6]),
)
这可行,但它很丑陋,并且是从我在网上某处找到的教程中摘录的。我的目标是让这些操作动态化。
示例类
class FileMeta(object):
def __init__(self, fullPathFileName, filename):
self.fullPathFileName = fullPathFileName
self.filename = filename
self.extension = os.path.splitext(self.filename)[1].lower()
...
def fileMetaList(self):
return [self.filename, self.extension, self.created, self.modified,\
self.size, self.owner, self.permissions]
所以这是场景:给定一个类对象
-
根据类成员变量动态定义表
列号和名称应与变量名对应
或对应于类变量列表中该变量的索引
编写一个函数,可以将类中的数据插入到对应的动态创建的表中
我的直觉告诉我这就是 SQLAlchemy 的优势所在。谁能告诉我一个很好的教程或参考,可以概述这个过程?
【问题讨论】:
你的意思是declarative object-relational configuration? 我不确定我的意思。我是 SQLAlchemy 的菜鸟。 【参考方案1】:您想改用declarative extension:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class FilePaths(Base):
__tablename__ = 'file_paths'
__table_args__ = 'mysql_engine':'InnoDB'
table_id = Column(Integer, primary_key=True)
fullpath = Column(String(255))
filename = Column(String(255))
extension = Column(String(255))
created = Column(String(255))
modified = Column(String(255))
size = Column(Integer)
owner = Column(String(255))
permissions = Column(Integer)
Base.metadata.create_all(engine)
您可以根据需要定义自己的__init__()
以及其他方法,然后创建这些方法的实例以插入新行。
请参阅SQLAlchemy's own ORM tutorial。
【讨论】:
@laycat:这是 OP 要求的:将表行反映为对象的类定义。您现在可以使用FilePath
实例,它们透明地反映数据库行内容。
Base 的 AutoMap() 是否也适用于动态创建表格? docs.sqlalchemy.org/en/rel_1_0/orm/extensions/automap.html
@DustyBoshoff 看起来像是为此目的而设计的,是的。请注意,该扩展是在 0.9.1 中添加的;这个答案是0.8天写的。
@DustyBoshoff:实际上,automapper
从现有模式(尽管是初级模式)创建声明性类; OP 试图手动创建类(这为您提供了更多的灵活性和控制力),但使用了错误的工具。【参考方案2】:
添加自动地图扩展:
from sqlalchemy.ext.automap import automap_base
# SQLAlchemy
engine = create_engine(DATABASE_URL)
metadata = MetaData()
Base = automap_base()
Base.prepare(engine, reflect=True)
【讨论】:
以上是关于使用 SQLAlchemy 基于类自动构建数据库表的主要内容,如果未能解决你的问题,请参考以下文章