在运行时将sqlalchemy数据库模式转换为django数据库模型。
项目描述
SqlAlchemy到Django桥梁
在运行时将sqlalchemy数据库模式转换为django数据库模型。
原始链接: https://github.com/mariushelf/sa2django
SqlAlchemy到Django桥梁允许您在SqlAlchemy中指定数据模型,并在Django中使用它们,而无需手动重新指定所有模型和字段以供Django ORM使用。
为什么使用这个包?
在SqlAlchemy中指定模式然后将其用于Django听起来似乎... 反直觉。有很多 为什么不 要回答...
为什么不直接在Django中指定模型?
有时,从Django提供的一些或全部数据由不属于Django应用程序的来源维护或创建。如果这些来源已经指定了完整的SqlAlchemy模型,那么SqlAlchemy到Django桥梁是有用的。
为什么不简单地使用inspectdb
来动态生成Django模型规范?
inspectdb 并非真正动态 -- 它一次生成一个Python文件,需要手动修改。每次数据模型发生变化时,都需要调整该Python文件。
此外,通常无法从数据库中自动推导出模型之间的所有关系。对于第三方数据源,关系通常不表现为数据库模式中的外键约束,而是在一些文档中解释这些关系,这些文档以人类可读但不适合机器阅读的形式解释这些关系。
如果SqlAlchemy模型已经包含所有这些关系,那么在运行时将SqlAlchemy模型转换为Django ORM是有意义的。
状态
SQLAlchemy到Django的桥接器在作者的用例中运行良好。
可能存在许多边界情况和SQLAlchemy的许多(或不那么复杂)的功能尚未(尚不支持)。
测试在sqlite中运行,我们的生产系统使用PostgreSQL。它可能或不与其它数据库系统兼容。
安装
pip install sa2django
特性
- 基本数据类型(int,float,字符串,varchar,char,日期,datetime等,bytea)
- 外键和一对多关系
- 包括
through
表的一对多关系 - 自动推断sqlalchemy
Base
中声明的所有模型 - 或者按照常规定义Django模型,但使用
SA2DModel
作为基类。然后所有数据库字段都将从相应的sqlalchemy模型中添加,但您仍然可以向Django模型添加属性和函数
用法
定义您的SQLAlchemy模式
假设您有以下SQLAlchemy模式
# sqlalchemy_schema.py
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
Base = declarative_base()
class Parent(Base):
__tablename__ = "parent"
id = Column(Integer, primary_key=True)
name = Column(String)
children = relationship("Child", back_populates="parent")
class Child(Base):
__tablename__ = "child"
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
parent_id = Column(Integer, ForeignKey("parent.id"))
parent = relationship(Parent, uselist=False, back_populates="children")
自动推断
您可以通过将以下代码添加到您的models.py
来在Django应用程序中使用它
# models.py
from sa2django.core import generate_sa2d_models, inject_models
from sqlalchemy_models import Base # this is what we have specified in the snippet above
_models = generate_sa2d_models(Base, __name__)
inject_models(_models, globals())
这将把类Child
和Parent
添加到您的models
模块中。这些类是与SQLAlchemy模型相对应的Django模型。
您在文件中看不到它们,但Django会识别它们,您可以在应用程序的任何地方导入它们,就像您手动声明了它们一样
from models import Parent, Child
print(Child.objects.all())
child = Child.objects.get(pk=my_pk)
print(child.parents.all())
注意:您的IDE可能会抱怨,因为它认为Parent
和Child
不存在。它不知道,因为类是在运行时创建的。代码将正常运行。
手动指定和自定义属性
Django的一个优点是它允许在模型上指定额外的属性。sa2django支持这一点。为此,您可以显式声明您的模型,并从sa2django.SA2DModel
继承,而不是从django.db.models.Model
继承,并在Meta
类下sa_model
属性中指定相应的SQLAlchemy模型。
您还需要使用register_table()
注册由SQLAlchemy模式中的任何模型引用的所有Django模型。
然后您就有控制权,可以控制类名和额外的属性,并仅使用sa2django
将所有字段和关系添加到您的Django模型中。
以下是一个示例
from sa2django import register_table, SA2DModel
from sa2django.core import extract_tables_from_base
import sqlalchemy_models
# extract all SQLAlchemy tables
_tables = extract_tables_from_base(sqlalchemy_models.Base)
# register the tables
for _tablename, _sa_class in _tables.items():
register_table(_tablename, _sa_class.__name__)
class Child(SA2DModel):
class Meta:
sa_model = sqlalchemy_models.Child
ordering = ["age"]
@property
def age_next_year(self):
return self.age + 1
class Parent(SA2DModel):
class Meta:
sa_model = sqlalchemy_models.Parent
目前不能混合手动和自动模型提取--如果您手动指定了一个模型,则不能再使用generate_sa2d_models()
,因此您需要手动指定所有模型。
限制
SQLAlchemy提供了Django功能的超集。因此,有一长串的限制。
列表甚至更长,可能不是详尽的,因为sa2django是一个针对作者当前需求定制的年轻项目。
- 目前只支持声明性基础定义,不支持纯
Mapper
对象 - 复合外键和主键不受支持。主键和外键必须包含恰好一个列
- 不使用外键的关系不会添加到Django模型中
多对多关系
-
在SQLAlchemy中,在中继表的映射器中,必须指定指向两个表的外键和关系。
示例
class CarParentAssoc(Base): __tablename__ = "cartoparent" id = Column(Integer, primary_key=True) car = relationship("Car") parent = relationship("Parent") car_id = Column(Integer, ForeignKey("car.car_id")) parent_id = Column(Integer, ForeignKey("parent.id"))
注意,对于指向
car
和parent
表的链接,都指定了外键和关系属性。
变更日志
0.2.1
- 限制到SQLAlchemy <1.4
0.2.0
- 从多对一关系推导出外键,而不是依赖于显式的外键列
0.1.3
- 为没有在SQLAlchemy中定义长度的字符串字段设置任意
max_length
为2048。这是必要的,因为Django不支持无限制的字符串字段,尽管一些后端(例如Postgres)支持
贡献
欢迎发送拉取请求!理想情况下,通过创建或回复Github票据来联系我们,以便我们协调我们的工作和想法。
许可证
作者:Marius Helf (helfsmarius@gmail.com)
项目详情
下载文件
下载适用于您平台的应用程序。如果您不确定选择哪个,请了解更多关于安装包的信息。
源代码分发
构建分发
sa2django-0.2.1.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 0f31eb1a7b2837eeb9f1b1f43eb04b6128bdf2983cf7bf3f45b4749a39643bcd |
|
MD5 | 93160b1ff462103510849f43376076ac |
|
BLAKE2b-256 | e8497f446764845b52d3a64956cd6d8396c893a94482fd9d5ac79ce02f11ce53 |
sa2django-0.2.1-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | a5732407deec7fdc512a20c9e9420db782cda715061252f823be34905fd8db93 |
|
MD5 | 5f3d08a928879a2cf3001caf8efae547 |
|
BLAKE2b-256 | a55e11d6362fb67679b43b1686cdbe15d234fe0bee6c44938bb6652cbfde3820 |