在运行时添加数据库支持

时间:2012-03-17 01:27:57

标签: python inheritance sqlalchemy

我有一个python模块,我多年来一直用它来处理一系列文本文件以便工作。我现在需要在db中存储一些信息(使用SQLAlchemy),但我仍然希望在没有db支持的情况下使用模块的灵活性,即不必实际使用sqlalchemy import(或已安装)。截至目前,我有以下内容......我一直在创建ProductDBProduct等等,这取决于我是否打算使用数据库。

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Product(object):
    pass

class WebSession(Product):
    pass

class Malware(WebSession):
    pass

class DBProduct(Product, Base):
    pass

class DBWebSession(WebSession, DBProduct):
    pass

class DBMalware(Malware, DBWebSession):
    pass

然而,我觉得必须有一个更简单/更清洁的方法来做到这一点。我觉得我正在创造遗产混乱和潜在的问题。理想情况下,我想创建一个ProductWebSession等类(可能使用装饰器),其中包含使用数据库所需的信息,但它只在调用类似的东西后启用/运行enable_db_support()。一旦调用了该函数,那么无论我创建什么对象,它本身(以及它继承的所有对象)都会启用所有列 绑定等。我还应该注意,如果我以某种方式弄清楚如何在一个类中包含ProductDBProduct,我有时需要同一个函数的两个版本:1如果db支持是启用,如果不是,则启用1。我在调用enable_db_support()时也考虑过“重新创建”对象层次结构,但这也是一场噩梦。

感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

在我看来,DRYest要做的就是抽象出数据存储格式的细节,无论是纯文本文件还是数据库。

也就是说,编写其他代码用来存储数据的某种抽象层,并使其成为可以在SQL或文本之间切换抽象层的输出。

或者换句话说,不要写一个ProductDB_Product类。而是编写一个store_data()函数,可以告诉他使用format='text'format='db'。然后在任何地方使用它。

这实际上是SQLAlchemy在幕后所做的事情 - 您不必为SQLAlchemy编写单独的代码,具体取决于它是否正在驱动mySQL,PostgreSQL等。这些都是在SQLAlchemy中处理的,并且您使用了抽象的(数据库中立的接口。


或者,如果您对SQLAlchemy的反对意见是它不是Python内置的,那么总是sqlite3。这为您提供了一个没有胖的SQL关系数据库的所有优点。


或者,交替使用sqlite3作为中间格式。因此,重写所有您的代码以使用sqlite3,然后根据需要从sqlite3转换为纯文本(或其他数据库)。在极限情况下,转换为纯文本只是sqlite3 db .dump away.

答案 1 :(得分:0)

好吧,您可以使用Classical Mapping创建纯粹的非数据库感知模型而不使用declarative扩展名。但是,在这种情况下,您将无法在SA中使用relationships,但对于简单的数据导入/导出类型的模型,这应该足够了:

# models.py
class User(object):
    pass

----

# mappings.py
from sqlalchemy import Table, MetaData, Column, ForeignKey, Integer, String
from sqlalchemy.orm import mapper
from models import User

metadata = MetaData()

user = Table('user', metadata,
            Column('id', Integer, primary_key=True),
            Column('name', String(50)),
            Column('fullname', String(50)),
            Column('password', String(12))
        )

mapper(User, user)

另一个选择是为某个其他模块中定义的模型创建一个基类,并在启动时使用configure这个基类是否支持DB,如果是DB-aware版本添加关系和引擎配置等附加功能......