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

Posted

技术标签:

【中文标题】SQLAlchemy:数据库创建代码小于数据库【英文标题】:SQLAlchemy: database creation code smaller than database 【发布时间】:2016-03-07 11:06:54 【问题描述】:

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

一个包含所有的类声明,开头是这样的:

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)

另一个文件导入类,并创建一些条目,如下所示:

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。

这是意料之中的,还是表明我的数据库结构混乱了?

【问题讨论】:

你的.py源代码大小与数据库大小无关。 但是适合 28KB 的 python 源代码(包括所有的导入、函数调用、语法和 cmets)的信息怎么会占用 .db 格式的 60KB 呢?如果有的话,我希望 .db 能够更好地利用空间。 @Selzuk,我猜第二个文件的大小可能与数据库的大小成正比,但是数据库会保留更多的东西,比如元数据,所以对于小数据来说它肯定会更高。如果我错了,请纠正我。 数据库通常也声明了额外的空间,例如用于索引。这将显示为“已用空间”,但实际上仍未使用。原因是索引需要一些松弛空间来快速填充新条目。 每个数据库都有自己的数据存储方式,有的效率更高,有的效率不高。您可以通过示例了解更多关于 SQLite 文件结构的信息:sqlite.org/fileformat2.html 【参考方案1】:

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

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

【讨论】:

以上是关于SQLAlchemy:数据库创建代码小于数据库的主要内容,如果未能解决你的问题,请参考以下文章

连接mysql数据库,创建用户模型

flask mysql sqlalchemy教程

from flask_sqlalchemy import SQLAlchemy 无法创建数据库表,代码无报错,代码如下,python版本是3.5

sql 可以运行,但是当你用 sqlalchemy 运行 python 代码时你失败了

python SQLAlchemy

flask数据库管理