【问题标题】:SQL Alchemy: how many "Base = declarative_base()" statements are required?SQLAlchemy:需要多少“Base = declarative_base()”语句?
【发布时间】:2020-02-11 01:27:16
【问题描述】:

我刚刚开始学习 SQL Alchemy,对于我的第一个项目,我的目标是创建两个单独的 SQLITE DB 文件,每个文件都有一个表。在我第一次尝试时,我尝试了以下方法:

Base = declarative_base() 

class HostInfo(Base):
    __tablename__ = 'hosts'

    id = Column(Integer, primary_key = True)
    ...

host_info_engine = create_engine('sqlite:///hostinfo.db', echo=False)
Base.metadata.create_all(host_info_engine)


class RecoveryLogger(Base):
    __tablename__ = 'recovery_entries'

    id = Column(Integer, primary_key=True)
    ....

recovery_log_engine = create_engine('sqlite:///recovery_logger.db', echo=False)
Base.metadata.create_all(recovery_log_engine)

这在大多数情况下是有效的,但一个意想不到的副作用是它在 hostinfo.db 中创建了两个表,这不是我想要的 - 我只想要一个表的数据库文件。经过一番摸索后,我能够检查 Base 并发现它包含了我的两个类声明中的所有列。我解决此问题的方法是在第二类声明 (RecoveryLogger) 之前插入另一个 Base = declarative_base() 语句,这似乎解决了问题。

这让我陷入了一个循环,因为我不认为来自子类的信息会返回到父类,但看起来确实如此,或者至少 Base似乎是某种特殊对象,可以从任何基于它的类中获取所有细节。

那么,解决这个问题的正确方法是什么?插入第二个 Base = declarative_base() 语句是正确的方法吗?我应该为每个 declarative_base() 分配使用不同的名称(而不是 Base)吗?

谢谢!

【问题讨论】:

  • 声明性基类'meta class 允许它执行各种“魔法”,例如保留所有继承自它的类的注册表。
  • 那么我应该为我正在使用的每个 SQLITE DB 创建一个单独的基础吗?
  • 如果他们不打算使用相同的模式,那么我会说是的。见stackoverflow.com/questions/36342716/…
  • 你能解释一下为什么你想得到两个数据库,每个数据库都只有一个表吗?如果您只想将两种数据类型存储在两个不同的文件中,SQL 数据库可能不是合适的存储方式。
  • 不确定这是否有助于您的情况,但会在这里投入 2 美分。我通过使用 SQLACodeGen 学习了 SQLAlchemy。 pypi.org/project/sqlacodegen您是否尝试过查看会生成数据库元数据的内容?然后将其与您的解决方案进行比较?

标签: python sqlite sqlalchemy


【解决方案1】:

你的方法很好。您确实应该为各个数据库声明单独的 Bases 。给这两个基地起不同的名字可能是个好主意,例如HostBaseLoggerBase,以提高代码的可扩展性和可重用性。这样,您可以使用各个基础向两个数据库(文件)添加和删除更多表,而不会混淆。重构/重新排序也更容易。下面是一个重新排序的例子。

HostBase = declarative_base()
LoggerBase = declarative_base() 

class HostInfo(HostBase):
    __tablename__ = 'hosts'

    id = Column(Integer, primary_key = True)
    ...

class RecoveryLogger(LoggerBase):
    __tablename__ = 'recovery_entries'

    id = Column(Integer, primary_key=True)
    ...

host_info_engine = create_engine(r'sqlite://hostinfo.db', echo=False)
HostBase.metadata.create_all(host_info_engine)

recovery_log_engine = create_engine(r'sqlite://recovery_logger.db', echo=False)
LoggerBase.metadata.create_all(recovery_log_engine)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 2016-07-20
    • 2020-08-26
    • 2020-02-08
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多