Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Alembic为几何体列生成任意类型更改_Python_Sqlite_Alembic_Spatialite_Geoalchemy2 - Fatal编程技术网

Python Alembic为几何体列生成任意类型更改

Python Alembic为几何体列生成任意类型更改,python,sqlite,alembic,spatialite,geoalchemy2,Python,Sqlite,Alembic,Spatialite,Geoalchemy2,我正在从事一个项目,该项目使用SQLite作为数据库,使用Alembic作为数据库迁移工具。它包括空间数据,因此,项目中包括空间扩展和地球炼金术2。我正在使用autogenerate命令,它检测到几何体列中不存在的一些更改 以下是项目的简化结构: #模型 sqlite_命名_约定={ “ix”:“ix%(列0标签)s”, “uq”:“uq%(表名称)s%(列名称)s”, “ck”:“ck%(表名)s%(列名)s”, “fk”:“fk%(表名)s%(列名)s%(引用表名)s”, “主键”:“主键%

我正在从事一个项目,该项目使用SQLite作为数据库,使用Alembic作为数据库迁移工具。它包括空间数据,因此,项目中包括空间扩展和
地球炼金术2
。我正在使用
autogenerate
命令,它检测到几何体列中不存在的一些更改

以下是项目的简化结构:

#模型
sqlite_命名_约定={
“ix”:“ix%(列0标签)s”,
“uq”:“uq%(表名称)s%(列名称)s”,
“ck”:“ck%(表名)s%(列名)s”,
“fk”:“fk%(表名)s%(列名)s%(引用表名)s”,
“主键”:“主键%(表名)s”,
}
元数据=元数据(命名约定=sqlite命名约定)
BaseSpatiaLite=声明性_库(元数据=元数据)
类别几何图形(BaseSpatiaLite):
__tablename_=“几何图形”
几何图形\u id=列(整数,主键=真)
几何图形=柱(
地球炼金术2.types.Geometry(Geometry_type=“Geometry”,srid=4326,management=True),
nullable=False,
)
name=Column(字符串(长度=150),null=False)
Alembic的
env.py
如下:

#env.py
...
def运行迁移在线()
可连接=引擎配置中的引擎配置(
config.get_节(config.config_ini_节),
prefix=“sqlalchemy.”,
poolclass=pool.NullPool,
)
#启用Spatialite扩展
监听(可连接,“连接”,加载空间)
#创建不存在的空间表
为sqlite创建空间表(可连接)
使用connectable.connect()作为连接:
context.configure(
连接=连接,
target\u metadata=target\u metadata,
将_渲染为_batch=True,
比较类型=真,
)
使用context.begin_transaction():
context.run_migrations()
创建几何图形表的第一个迁移脚本:

。。。
def升级():
op.create_表(
“几何学”,
sa.Column(“geometry_id”,sa.Integer(),nullable=False),
sa.Column(“geometry”,geoalchemy2.types.geometry(management=True),nullable=False),
sa.Column(“name”,sa.String(长度=150),nullable=False),
sa.PrimaryKeyConstraint(“几何体id”),
)
def降级():
op.drop_表(
“几何学”,
)
运行此迁移脚本后,将正确创建表:

当我再次运行
autogenerate
命令时,它应该没有发现任何更改。但是,它会生成具有任意类型更改的迁移脚本:

def升级():
将op.batch_alter_table(“几何图形”,schema=None)作为batch_op:
批处理操作更改列(
“几何学”,
现有类型=sa.NUMERIC(),
类型=地球炼金术2.types.Geometry(srid=4326,management=True),
nullable=False,
)
def降级():
将op.batch_alter_table(“几何图形”,schema=None)作为batch_op:
批处理操作更改列(
“几何学”,
现有类型=地球炼金术2.types.Geometry(srid=4326,management=True),
类型=sa.NUMERIC(),
nullable=True,
)

我知道我可能会将
compare\u type
参数设置为
False
,但我想自动检测类型更改。有没有办法告诉Alembic,
geometry
列的类型是
geometry
,并且没有任何变化?

我找到了一个解决方案。我在这里分享它,以防其他人可能会遇到此错误:()

可以实现自定义的
compare\u type
函数,并在
env.py
中使用它。在我的例子中,
geometry
列被解释为
sqlalchemy.Integer
sqalchemy.NUMERIC
类型。这就是为什么我添加了一个if子句,它
返回False
如果检查类型为
数值
整数
,元数据类型为
地球炼金术2.types.Geometry

# add it to env.py
def custom_compare_type(
    context, 
    inspected_column, 
    metadata_column, 
    inspected_type, 
    metadata_type
):
# return False if the metadata_type is the same as the inspected_type
# or None to allow the default implementation to compare these
# types. a return value of True means the two types do not
# match and should result in a type change operation.
if (isinstance(inspected_type, NUMERIC) or isinstance(inspected_type, Integer)) and isinstance(
    metadata_type, Geometry
):
    return False

return None
当您将
compare\u type=True
更改为
compare\u type=custom\u compare\u type
时,Alembic应该停止检测
几何体
列的任意类型更改

注意:Alembic仍然检测到可空性更改,但与
compare\u type
问题无关