Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在运行时添加数据库支持_Python_Inheritance_Sqlalchemy - Fatal编程技术网

Python 在运行时添加数据库支持

Python 在运行时添加数据库支持,python,inheritance,sqlalchemy,Python,Inheritance,Sqlalchemy,我有一个python模块,多年来我一直在使用它来处理一系列文本文件。我现在需要在数据库中存储一些信息(使用SQLAlchemy),但我仍然希望在没有数据库支持的情况下灵活使用模块,即不必实际导入(或安装)SQLAlchemy。截至目前,我有以下几点。。。我一直在创建产品或数据库产品,等等,这取决于我是否打算使用数据库 from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class

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

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
然而,我觉得必须有一种更简单/更干净的方法来做到这一点。我觉得我正在创造一个继承混乱和潜在的问题。理想情况下,我希望创建一个包含使用db所需信息的
产品
WebSession
等类(可能使用装饰器),但它只有在调用类似
启用db\u支持()
之类的函数后才启用/起作用。调用该函数后,无论创建什么对象,它本身(以及它继承的所有对象)都将启用所有列 绑定等。我还应该注意,如果我不知怎么搞清楚如何在一个类中包含
Product
DBProduct
,我有时需要相同函数的两个版本:启用db支持时调用1个,未启用时调用1个。我还考虑过在调用
enable\u db\u support()
时“重新创建”对象层次结构,但这也变成了一场噩梦


非常感谢您的帮助。

在我看来,最干的事情就是将数据存储格式的细节提取出来,无论是纯文本文件还是数据库

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

或者换句话说,不要编写
产品
DB_产品
类。相反,编写一个
store_data()
函数,可以告诉它使用
format='text'
format='db'
。然后到处使用

这实际上与SQLAlchemy在幕后所做的事情是一样的——您不必为SQLAlchemy编写单独的代码,这取决于它是否在驱动mySQL、PostgreSQL等。所有这些都在SQLAlchemy中处理,并且您使用抽象的(与数据库无关的)接口


或者,如果您反对
SQLAlchemy
是因为它不是Python内置的,那么总会有
sqlite3
。这给了您SQL关系数据库的所有优点,而没有fat



或者,使用
sqlite3
作为中间格式。因此,重写all您的代码以使用
sqlite3
,然后根据需要将
sqlite3
转换为纯文本(或其他数据库)。在极限情况下,转换为纯文本只是一个

好吧,您可以通过使用而不使用声明性扩展创建一个纯的非DB感知模型。但是,在这种情况下,您将无法使用SA中使用的
关系
,但对于模型的简单数据导入/导出类型,这应该足够了:

# 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)


另一种选择是在其他模块中为您的模型定义一个基类,并在启动时将该基类配置为DB感知或非DB感知,并且在DB感知版本的情况下添加其他功能,如关系和引擎配置…

可以采用
存储数据()
方法,然而,我将失去
SQLAlchemy
提供的“无缝性”。此外,我必须记住调用该函数,可能还有另一个函数用于更新。我不反对使用SQLAlchemy,事实上,这就是我在数据库中持久化数据时使用的方法。但是,在许多情况下,我(或同事)不需要将数据保存在数据库中。在这些情况下,我希望SQLAlchemy(或db驱动程序)不是必需的安装/导入。感谢您的响应。这可能对我有用。我只需要调查一下关系问题。我倾向于依赖
关系
很多,但它仍然可能有效。谢谢。我越想越想,我想我考虑过采用这种方法,但没有考虑,因为在数据库中存储信息时,可能需要重写某些类定义的函数。您知道是否有可能(或者我将如何着手)使用这种方法重新定义一些类的函数吗?再次感谢。@redlamb:好吧,由于强大的python的强大功能,您总是可以在
enable\u db\u support()
中添加关系,只需将方法分配给一个类:
DBProduct.versions=relationship('ProductVersion',…)
。同样,您可以重写方法:您只需定义一个新的(未绑定的)方法,如
def db\u override\u me(self,param1,…)
,然后(重新)将其分配给类:
DBProduct.override\u me=db\u override\u me
。虽然我担心这类设计可能会有更好的解决方案……我确实采用了你的方法,但是在做了更多的研究之后,我能够与你建立关系。您只需要在启动时提供
属性
参数。