简体   繁体   中英

SQLAlchemy: database creation code smaller than database

I have two python files with which I create a database:

One contains all the class declarations, and starts like this:

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)

The other file imports the classes, and creates some entries, starting like this:

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)

These files are 13KB and 28KB respectively - while the databse file they produce is 60KB.

Is this to be expected, or is it indicative of my database structure being messed up?

SQLite database files are organized into pages (with the default page size probably being 4 KB), and tables or indexes cannot share pages. Therefore, you will need at least one page for each database object.

New rows will be able to use the free space in these pages, so inserting the first few records will not increate the database file size.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM