SQLAlchemy:数据库创建代码比数据库小

SQLAlchemy: database creation code smaller than database

我有两个 python 文件用来创建数据库:

一个包含所有 class 的声明,并且这样开始:

from sqlalchemy import create_engine, Column, Integer, String, Sequence, Table, ForeignKey, Float, DateTime, ForeignKeyConstraint
from sqlalchemy.orm import backref, relationship, sessionmaker
from os import path

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

genotype_association = Table('gt_association', Base.metadata,
    Column('genotypes_id', Integer, ForeignKey('genotypes.id')),
    Column('animals_id', Integer, ForeignKey('animals.id'))
)
treatment_association = Table('tr_association', Base.metadata,
    Column('chronic_treatments_id', Integer, ForeignKey('chronic_treatments.id')),
    Column('animals_id', Integer, ForeignKey('animals.id'))
)
substance_association = Table('st_association', Base.metadata,
    Column('substance_administrations_id', Integer, ForeignKey('substance_administrations.id')),
    Column('solutions_id', Integer, ForeignKey('solutions.id'))
)
operator_association = Table('op_association', Base.metadata,
    Column('operator_id', Integer, ForeignKey('operators.id')),
    Column('fmri_measurements_id', Integer, ForeignKey('fmri_measurements.id'))
)
ingredients_association = Table('ig_association', Base.metadata,
    Column('solutions_id', Integer, ForeignKey('solutions.id')),
    Column('ingredients_id', Integer, ForeignKey('ingredients.id'))
)
laser_association = Table('ls_association', Base.metadata,
    Column('laser_stimulation_protocols_id', Integer, ForeignKey('laser_stimulation_protocols.id')),
    Column('fmri_measurements_id', Integer, ForeignKey('fmri_measurements.id'))
)

#general classes:

class Operator(Base):
    __tablename__ = "operators"
    id = Column(Integer, primary_key=True)
    code = Column(String, unique=True)
    full_name = Column(String)
    affiliation = Column(String)

class MeasurementUnit(Base):
    __tablename__ = "measurement_units"
    id = Column(Integer, primary_key=True)
    code = Column(String, unique=True)
    long_name = Column(String)
    siunitx = Column(String)

class Ingredient(Base):
    __tablename__ = "ingredients"
    id = Column(Integer, primary_key=True)
    code = Column(String, unique=True)
    name = Column(String)
    concentration = Column(Float, default=100)
    concentration_unit_id = Column(String, ForeignKey('measurement_units.id'))
    concentration_unit = relationship("MeasurementUnit")
    supplier = Column(String)
    supplier_id = Column(String)
    contained = Column(Integer, ForeignKey("ingredients.id"))
    contains = relationship("Ingredient")

class Solution(Base):
    __tablename__ = "solutions"
    id = Column(Integer, primary_key=True)
    code = Column(String, unique=True)
    name = Column(String)
    supplier = Column(String)
    supplier_id = Column(String)
    contains = relationship("Ingredient", secondary=ingredients_association, backref="ingredient_of")

    def __repr__(self):
        return "<Solution(name='%s' (long_name='%s'), concentration=%s%s contains: %s)>"\
        % (self.name, self.long_name, self.concentration, self.concentration_unit, self.contains)

另一个文件导入 classes,并创建一些条目,这样开始:

from sqlalchemy import create_engine, literal
from os import path
from common_classes import *
from sqlalchemy.orm import sessionmaker
from add import loadSession, commit_and_close, double_entry
from datetime import datetime

def initialize_main_entries(db_path):
    session,engine = loadSession(db_path)

    christ = Operator(code="Chr", full_name="Horea Christian", affiliation="ETH")

    #Measurement Units
    s = MeasurementUnit(code="s", long_name="second", siunitx="\second")
    session.add(s)
    g = MeasurementUnit(code="g", long_name="gram", siunitx="\gram")
    hz = MeasurementUnit(code="Hz", long_name="hertz", siunitx="\hertz")
    session.add(hz)
    percent = MeasurementUnit(code="%", long_name="percent", siunitx="\percentt")
    session.add(percent)
    mi = MeasurementUnit(code="min", long_name="minute", siunitx="\arcminute")
    session.add(mi)
    mg_l = MeasurementUnit(code="mg/l", long_name="milligram per litre", siunitx="\milli\gram\per\litre")
    mg_ml = MeasurementUnit(code="mg/ml", long_name="milligram per millilitre", siunitx="\milli\gram\per\milli\litre")
    mul_g = MeasurementUnit(code="mul/g", long_name="microlitre per gram", siunitx="\micro\litre\per\gram")

    #Ingredients
    flu = Ingredient(name="Fluoxetine Hydrochloride", concentration="2.25", concentration_unit=mg_ml, supplier="Tocris")
    med = Ingredient(name="Medetomidine", concentration=38.5, concentration_unit=mg_l, supplier="Provert AG, Orion Pharma", supplier_id="DOMITOR")
    sal = Ingredient(name="Sodium Chloride", concentration=86.535, concentration_unit=mg_ml)
    sal_flu = Ingredient(name="Sodium Chloride", concentration=997.75, concentration_unit=mg_ml)
    iso_3 = Ingredient(name="Isoflurane", concentration=3, concentration_unit=percent, supplier="Piramal Healthcare")
    iso_05 = Ingredient(name="Isoflurane", concentration=0.5, concentration_unit=percent, supplier="Piramal Healthcare")
    air = Ingredient(name="Air", concentration=80, concentration_unit=percent)
    oxy = Ingredient(name="Oxygen", concentration=20, concentration_unit=percent)
    e_air_3 = Ingredient(name="Enriched Air", concentration=97, concentration_unit=percent, contains=[air, oxy])
    e_air_05 = Ingredient(name="Enriched Air", concentration=99.5, concentration_unit=percent, contains=[air, oxy])
    rnasea10 = Ingredient(name="RNase A", concentration=10, concentration_unit=mg_ml)

这些文件分别为 13KB 和 28KB - 而它们生成的数据库文件为 60KB。

这是预料之中的,还是表明我的数据库结构被搞砸了?

SQLite 数据库文件被组织成页面(默认页面大小可能是 4 KB),表或索引不能共享页面。 因此,每个数据库对象至少需要一页。

新行将能够使用这些页面中的空闲 space,因此插入前几条记录不会增加数据库文件的大小。