SqlAlchemy学习总结

1 安装

pip install sqlalchemy

2 创建Engine

2.1 数据库连接协议:

SQLite: sqlite:///./mydb.db  "sqlite:///:memory:"(内存型)
MySQL: mysql://username:password@hostname/database_name
PostgreSQL: postgresql://username:password@hostname/database_name
SQL Server: mssql+pyodbc://username:password@hostname/database_name?driver=ODBC+Driver+17+for+SQL+Server
Oracle: oracle+cx_oracle://username:password@hostname:port/service_name
MariaDB: mariadb://username:password@hostname/database_name
MongoDB: mongodb+srv://username:password@cluster_name/database_name

2.2 示例语法:
from sqlalchemy import create_engine
# echo: python日志记录器输出
engine = create_engine("sqlite+pysqlite:///./mydb.db:", echo=True)

3 创建Connection

# from sqlalchemy import text
# 方式1:
with engine.connect() as conn:
    result = conn.execute(text("select 'hello world'"))
    print(result.all())
    
# 方式2:
with session.connection() as conn:
    result = conn.execute(text("select 'hello world'"))
    print(result.all())

4 读取表数据

# 以行读取
from sqlalchemy import text

with engine.connect() as conn:
	result = conn.execute(text("SELECT x, y FROM some_table"))

# 元组赋值
for x, y in result:
...

# 整数索引
for row in result:
x = row[0]
y = row[1]

# 属性名称
for row in result:
print(f"x: {row.x}  y: {row.y}")

# 映射访问:
for dict_row in result.mappings():
x = dict_row["x"]
y = dict_row["y"]

5 execute传参

# ":num": 以"冒号"开头来定义占位参数,然后方法的第二个参数以“{}”的形式进行传参
result = conn.execute(text("SELECT x, y FROM some_table WHERE y > :num"), {"num": 2})

# 多个参数:以“[{},{},...]”形式传参
conn.execute(
  text("INSERT INTO some_table (x, y) VALUES (:x, :y)"),
  [{"x": 11, "y": 12}, {"x": 13, "y": 14}],
)

6 MetaData

6.1  应用场景:

主要和表结构相关:reflect(表结构反射)、orm

# reflect:把数据库中的表结构信息反射到MetaData对象中
# orm:通过模型类创建表到数据库

6.2 reflect:
engine = create_engine('sqlite:///mydb.db')
# 创建 Metadata 对象
metadata_obj = MetaData(bind=engine)
# 从数据库中读取表格结构信息并反映到 Metadata 对象中
metadata_obj.reflect()
# 打印反映后的表格信息
for table in metadata_obj.tables.values():
    print("Table Name:", table.name)
    print("Columns:")
    for column in table.columns:
        print("\tColumn Name:", column.name)
        print("\tData Type:", column.type)
  
 
# 为Table设置MetaData        
from sqlalchemy import Table, Column, Integer, String
user_table = Table(
    "user_account",
    metadata_obj,
    Column("id", Integer, primary_key=True),
    Column("name", String(30)),
    Column("fullname", String),
    extend_existing=True
)
# user_table.primary_key
# user_table.c.name
# user_table.c.keys()
 6.3 表创建:
metadata_obj.create_all(engine)

# 未绑定engine:sqlalchemy.exc.UnboundExecutionError: MetaData object is not bound to an Engine or Connection.  Execution can not proceed without a database to execute against.
metadata_obj = MetaData(bind=engine)

# 表已存在:sqlalchemy.exc.InvalidRequestError: Table 'user' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
user_table = Table(
     "user",
     metadata_obj,
     ...,
     extend_existing=True
)

7 声明式orm

7.1 1.x版本:
# 注:2.0版本语法参考sqlalchemy(2.0)小结
from sqlalchemy import Column
from sqlalchemy.orm import relationship
from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
	pass

class User(Base):
  __tablename__ = "user_account"

     id = Column(Integer, primary_key=True)
     name = Column(String(30), nullable=False)
     fullname = Column(String)
  addresses = relationship("Address", back_populates="user")

class Address(Base):
  __tablename__ = "address"

     id = Column(Integer, primary_key=True)
     email_address = Column(String, nullable=False)
     user_id = Column(ForeignKey("user_account.id"), nullable=False)
  user = relationship("User", back_populates="addresses")
7.2 创建表:
Base.metadata.create_all(engine)

8 创建对象并持久化

8.1 创建会话:
# 以下两种方式创建会话本质没区别
# 方式1:
from sqlalchemy.orm import sessionmaker
session = sessionmaker(bind=engine)

# 方式2:
from sqlalchemy.orm import Session
session = Session(bind=engine)
8.2 持久化:
from sqlalchemy.orm import Session

with Session(engine) as session:
spongebob = User(
  name="spongebob",
  fullname="Spongebob Squarepants",
  addresses=[Address(email_address="spongebob@sqlalchemy.org")],
)
sandy = User(
  name="sandy",
  fullname="Sandy Cheeks",
  addresses=[
      Address(email_address="sandy@sqlalchemy.org"),
      Address(email_address="sandy@squirrelpower.org"),
  ],
)
patrick = User(name="patrick", fullname="Patrick Star")
session.add_all([spongebob, sandy, patrick])
session.commit()

9 CRUD(sqlalchemy.x)

9.1 简要:
在sqlalchemy包中,已经封装了crud的方法,可以很方便调用,从而不去写sql。
注意仅是将sql语句的方法化,执行这些方法并不是“执行sql”。
from sqlalchemy import insert,delete,update,select

# 示例model实例,供下面参考(采用1.x版本语法)
class User(Base):
     __tablename__ = "users"
     id = Column(Integer,primary_key=True)
     name = Column(String(30))
     fullname = Column(String)
9.2 crud:
# insert
stmt = (
    insert(User).
    values(name="jd",fullname="joden")
)

# delete
stmt = (
    delete(User).
    where(User.name=="jd")
)

# update
stmt = (
    update(User).
    where(User.name=="u1").
    values(name="j1")
)

# select
stmt = (
    select(User).
    where(name=="j1")
)
9.3 执行sql:
# 正如“简要”中提到,执行上述方法并没有执行sql(产生数据库变化)
# 如下语句将执行sql:

insert_stmt = (
     insert(User).
     values(name="jd",fullname="joden")
)

from sqlalchemy import create_engine
# url = "sqlite:///./t1.db"
engine = create_engine(url)
with engine.connect() as conn:
     conn.execute(insert_stmt)
     conn.commit()

 
 
# 另外地,如果是select(查询操作),也可以使用session.scalar(stmt)/scalars(stmt)来获取以实例为标量的查询集
from sqlalchemy.orm import Session
session = Session(engine)

res = session.scalars(stmt)
for row in res:
    print(row.name,row.fullname)

10 CRUD(session.x)

10.1 简要:

        与sqlalchemy.x中的不同的是,session.x中的crud方法会在当前会话中执行,在会话管理中作为数据库待定操作集,但是仍然需要我们去做会话(事务)提交才能真正做出数据库操作。

        所以说简单较少的数据库操作可以简单通过sqlalchemy.x中方法,而较多的数据库操作集则用session.x中方法比较好。

10.2 方法:  
方法描述
add(obj)将对象添加到会话中以进行持久化。
add_all(objs)将多个对象添加到会话中以进行持久化。
delete(obj)从会话中删除对象以进行持久化。
query()创建一个查询对象,用于执行数据库查询。
get(obj,id)根据id获取单个对象
merge(obj)将对象合并到会话中以进行持久化。
commit()提交会话中所有待定的事务。
flush()将所有待定的数据库操作发送到数据库。
expire(obj)将对象的属性从缓存中标记为过期。
refresh(obj)重新加载对象的属性值。
rollback()回滚会话中所有未提交的事务。
close()关闭会话。
10.3 简单示例:  
# select by id
sandy = session.get(User, 2)
# select
session.query(User).where(name="joden")
session.query(User.name,User.age).where(name="joden")

# add 
u1 = User(name="j1",fullname="joden1")
u2 = User(name="j2",fullname="joden2")
# session.add(u1)
session.add_all([u1,u2])

# delete
session.delete(u1)

# update
u1.name = "jd1"

# session commit
session.commit()
10.4 session.flush:

# 应用场景
 (1)获取新创建对象的主键值: 如果你需要在创建对象后立即获取其分配的主键值,那么在插入操作后执行 flush() 方法是必要的。否则,新创建的对象的主键值将不会在对象上更新,直到事务提交后才会更新。
 (2)处理数据库的唯一约束和触发器: 在某些情况下,数据库中的唯一约束或触发器可能会影响到插入或更新操作。执行 flush() 可以确保你及时地发现并处理任何由于约束或触发器引发的异常。
 (3)在需要确保数据一致性的操作中: 在一些需要确保数据一致性的复杂操作中,flush() 可以帮助你将操作分阶段提交到数据库,确保在整个操作过程中数据库的状态保持一致。

u4 = User(name="j4",fullname="joden4")
session.add(u4)
session.flush()
# print(u4.id)
session.commit()

11 execute

在sqlalchemy中使用execute(stmt)来执行sql。
要注意的是,可通过不同的实例来调用execute,下面我们将来了解几者的区别。

(1)engine.connect().execute(stmt)
(2)session.execute(stmt) 
(3)session.connection().execute(stmt) # 本质上是engine.connect().execute(stmt)

所以区别仅在于Connection对象还是Session对象执行,很明显通过Connection对象方式需要自己创建管理连接,而Session对象方式直接执行则不需要(但是需要关闭当前“会话”)。

12 session状态

语法描述
session.dirty查看当前会话中修改对象
session.new查看当前会话中添加对象

13 别名

13.1 字段别名:
for row in session.query(User.name.label("name_label")).all():
	print(row.name_label)
13.2 表别名:
from sqlalchemy.orm import aliased

user_alias = aliased(User, name="user_alias")

for row in session.query(user_alias).all():
	print(row.name)

14 过滤

14.1 filter_by:
for (name,) in session.query(User.name).filter_by(fullname="joden"):
	print(name)
14.2 filter:
# 较为灵活,支持python逻辑运算符
for (name,) in session.query(User.name).filter(User.fullname == "joden"):
	print(name)


# 常用操作
query.filter(User.name == "ed")
query.filter(User.name != "ed")
query.filter(User.name.like('%ed%'))
query.filter(User.name.in_(["ed", "wendy", "jack"]))
query.filter(User.name.in_(session.query(User.name))
14.3 链式调用:
# 无论是filter还是filter_by都可以链式调用
session.query(User).filter(User.name == "j1").filter(User.fullname == "joden1")
14.5 and_:
from sqlalchemy import and_
query.filter(and_(User.name == 'ed', User.fullname == 'Ed Jones'))
# 等价下面两种方式
query.filter(User.name == 'ed', User.fullname == 'Ed Jones')
query.filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')
14.6 text:
from sqlalchemy import text

# 基础语法
session.query(User).filter(text("id<224"))
# 使用占位参数
session.query(User).filter(text("id<:value and name=:name")).params(value=3, name="jd")

15 join查询

15.1 隐式内连接:
session.query(User, Address)
 .filter(User.id == Address.user_id)
 .filter(Address.email_address == "jack@google.com")
 .all()
15.2 显示内连接:
session.query(User)
	.join(Address)
	.filter(Address.email_address == "jack@google.com")
15.3 外连接:
# LEFT OUTER JOIN
query.outerjoin(User.addresses)  
query.outerjoin(Address)  

# select_from 控制左右外连接
query = session.query(User, Address).select_from(Address).join(User)

16 表关系

16.1 一对多:
### 方式一:
# (1) 在两表中各定义
relationship(
     association_table_name,
     back_populates=association_table_attr 	# 在关联表中定义的关联属性
)
# (2) 在子表中定义外键属性(字段)
parent_table_id = Column(ForeignKey("parent_table_name.id"))


### 方式二:
# (1) 在一表中定义
relationship(
     association_table_name,
     backref=association_table_attr
)
# (2) 在子表中定义外键属性(字段)
parent_table_id = Column(ForeignKey("parent_table_name.id"))



### 示例代码
class TB1(Base):
     __tablename__ = 'tb1'

     id = Column(Integer,primary_key=True)
     name = Column(String(20))
     t2 = relationship("TB2",backref="t1")

class TB2(Base):
     __tablename__ = 'tb2'

     id = Column(Integer,primary_key=True)
     name = Column(String(20))
     t1_id = Column(ForeignKey("tb1.id"))


### 一对多关联查询
session.query(TB1).first().t2
16.2 多对多:
### 方式一:
association_table = Table(
    "association_table",
    Base.metadata,
    Column("left_id", ForeignKey("left_table.id"), primary_key=True),
    Column("right_id", ForeignKey("right_table.id"), primary_key=True),
)

class Parent(Base):
    __tablename__ = "left_table"
    id = Column(Integer, primary_key=True)
    children = relationship(
        "Child", secondary=association_table, back_populates="parents"
    )

class Child(Base):
    __tablename__ = "right_table"
    id = Column(Integer, primary_key=True)
    parents = relationship(
        "Parent", secondary=association_table, back_populates="children"
    )


### 方式二:
association_table = Table(
    "association_table",
    Base.metadata,
    Column("left_id", ForeignKey("left_table.id"), primary_key=True),
    Column("right_id", ForeignKey("right_table.id"), primary_key=True),
)

class Parent(Base):
    __tablename__ = "left_table"
    id = Column(Integer, primary_key=True)
    children = relationship("Child", secondary=association_table, backref="parents")

class Child(Base):
    __tablename__ = "right_table"
    id = Column(Integer, primary_key=True)
16.3 一对一:
# 一对一通过添加uselist=False参数即可
class Parent(Base):
     __tablename__ = "parent_table"
     id = Column(Integer, primary_key=True)
     child = relationship("Child", back_populates="parent", uselist=False)

class Child(Base):
     __tablename__ = "child_table"
     id = Column(Integer, primary_key=True)
     parent_id = Column(Integer, ForeignKey("parent_table.id"))

     # many-to-one side remains, see tip below
     parent = relationship("Parent", back_populates="child")

17 backref和back_populates

17.1 区别:

        backref 是 back_populates 的一种简化形式。backref 允许你在定义关系的同时,在另一个表格中自动创建一个反向引用属性,而不需要显式地在另一个表格的 relationship() 中设置 back_populates。

17.2 back_populates:  
class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)
    children = relationship("Child", back_populates="parent")

class Child(Base):
    __tablename__ = 'children'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parents.id'))
    parent = relationship("Parent", back_populates="children")
17.3 backref:  
class Parent(Base):
     __tablename__ = 'parents'
     id = Column(Integer, primary_key=True)
     children = relationship("Child", backref="parent")

class Child(Base):
     __tablename__ = 'children'
     id = Column(Integer, primary_key=True)
     parent_id = Column(Integer, ForeignKey('parents.id'))

18 session.query

18.1 执行简单查询:
from sqlalchemy.orm import sessionmaker

Session = sessionmaker(bind=engine)
session = Session()

# 查询所有记录
result = session.query(User).all()


for instance in session.query(User).order_by(User.id):
	print(instance.name, instance.fullname)
18.2 常用查询:
# 过滤查询: 你可以使用 `filter()` 方法对查询结果进行过滤。
result = session.query(User)
    .filter(User.age > 25)
    .all()

# 排序查询: 使用 `order_by()` 方法对查询结果进行排序。
result = session.query(User)
    .order_by(User.age.desc())
    .all()

# 连接查询: 你可以执行连接查询来检索相关联的对象。
result = session.query(User, Address)
    .join(Address)
    .filter(User.id == Address.user_id)
    .all()

# 聚合查询: 使用 `func` 函数进行聚合查询。
from sqlalchemy import func
result = session.query(func.count(User.id)).scalar()

# 子查询: 你可以在查询中使用子查询来执行复杂的操作。
subquery = session.query(Address.user_id).filter(Address.city == 'New York')
result = session.query(User).filter(User.id.in_(subquery)).all()

19 sqlalchemy(2.0)

19.1 声明映射类:
# 不同:使用python类型简化类型声明
# 注意:对于字符串类型字段,如果在mysql中创建则必须要给定长度(sqlite、PostgreSQL中则不用)

from typing import List
from typing import Optional

from sqlalchemy import ForeignKey, String
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship
from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
 	pass

class User(Base):
     __tablename__ = "user_account"
     id: Mapped[int] = mapped_column(primary_key=True)
     name: Mapped[str] = mapped_column(String(30))
     fullname: Mapped[Optional[str]]  # 必要时要补全
     addresses: Mapped[List["Address"]] = relationship(back_populates="user")

     def __repr__(self) -> str:
         return f"User(id={self.id!r}, name={self.name!r}, fullname={self.fullname!r})"


class Address(Base):
     __tablename__ = "address"
     id: Mapped[int] = mapped_column(primary_key=True)
     email_address: Mapped[str] # 必要时要补全
     user_id = mapped_column(ForeignKey("user_account.id"))
     user: Mapped[User] = relationship(back_populates="addresses")

     def __repr__(self) -> str:
         return f"Address(id={self.id!r}, email_address={self.email_address!r})"
19.2 抽离重复类型字段:
# 比如主键用到的比较多且类型一致:整型、主键
# 2.0后可以使用类型注解的形式来对重复字段类型进行抽离定义,从而来简化字段声明

from typing_extensions import Annotated
from sqlalchemy.orm import Mapped

str50 =  Annotated[str, mapped_column(String(50))]
intpk = Annotated[int, mapped_column(primary_key=True)]
user_fk = Annotated[int, mapped_column(ForeignKey("user_account.id"))]


class User(Base):
 	name:Mapped[str50]

20 数据迁移(alembic)

20.1 安装迁移依赖:

pip install alembic

20.2 迁移须知:

1. 使用alembic迁移配置需要导入基类Base,此时只能通过declarative_base()来创建,而不能通过DeclarativeBase来创建

2. 对于数据库迁移,我们始终需要两个信息:
    (1) 要迁移到的数据库
    (2) 要迁移的表
    
3. 所以使用alembic初始化我们需要配置以上的两个信息:
    初始化命令(项目根目录下执行,一般与app目录同级):alembic init alembic
    
4. 配置两个信息:
    (1) 数据库信息:alembic.ini中的sqlalchemy.url进行配置
    (2) 要迁移的表:因为要迁移的表都与基类Base所关联,并且sqlalchemy创建表是通过Base.metadata来创建表到数据库,所以alembic要求我们配置Base.metadata,在alembic/env.py中的target_metadata进行配置

20.3 数据迁移:

# 安装好依赖,并且定义好所需的表模型后,我们将开始迁移
# 1. 初始化配置:alembic init alembic
# 2. 生成迁移文件:alembic revision --autogenerate -m [message](该message是迁移备注信息,可以自己定义)
# 3. 开始迁移:alembic upgrade head

# 注:我们可以关注每一步迁移命令产生的变化或文件,从而有利于我们进一步了解迁移的本质

21 英语词汇

Declare:声明        typically:通常         conjunction:结合        persist:持久化         

emit:发出        abbreviated:缩写     particular:特定

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/498294.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件工程学习笔记10——开发编码篇2

开发编码篇 一、软件工程师的核心竞争力1、学习能力2、解决问题的能力&#xff08;1&#xff09;发现问题&#xff08;2&#xff09;分析问题&#xff08;1&#xff09;解决问题 3、影响力4、总结 二、如何提升软件工程师的核心竞争力1、如何提升学习能力2、如何提高解决问题的…

【python 数据可视化】 WordCloud词云图

目录 词云简介 准备工作 安装方法一&#xff1a; 安装方法二&#xff1a; 生成词云步骤 数据预处理&#xff1a; 分词&#xff1a; 统计词频出现的次数&#xff1a; 去除词语&#xff1a; 生成词云&#xff1a; 显示词云&#xff1a; 保存词云&#xff1a; 完整代码 词…

Docker搭建LNMP环境实战(07):安装nginx

1、模拟应用场景描述 假设我要搭建一个站点&#xff0c;假设虚拟的域名为&#xff1a;api.test.site&#xff0c;利用docker实现nginxphp-fpmmariadb部署。 2、目录结构 2.1、dockers根目录 由于目前的安装是基于Win10VMWareCentOS虚拟机&#xff0c;同时已经安装了VMWareT…

状态压缩DP【蒙德里安的梦想】

题目描述 输入样例 1 2 1 3 1 4 2 2 2 3 2 4 2 11 4 11 0 0输出样例 1 0 1 2 3 5 144 51205题目链接 https://www.acwing.com/problem/content/293/ 分析 总方案数即为横放的方案数&#xff0c;因为横放完后列填补只会出现一种情况1表示横放&#xff0c;0表示竖放如果合并…

实验2-spark编程

实验目的 &#xff08;1&#xff09;通过实验掌握Spark的基本编程方法&#xff1b; &#xff08;2&#xff09;熟悉RDD到DataFrame的转化方法&#xff1b; &#xff08;3&#xff09;熟悉利用Spark管理来自不同数据源的数据。 实验内容 1&#xff0e;Spark基本操作 请参照…

OpenPLC_Editor 在Ubuntu 虚拟机安装记录

1. OpenPLC_Editor在虚拟机上费劲的装了一遍&#xff0c;有些东西已经忘了&#xff0c;主要还是python3 的缺失库版本对应问题&#xff0c;OpenPLC_Editor使用python3编译的&#xff0c;虚拟机的Ubuntu 18.4 有2.7和3.6两个版本&#xff0c;所以需要注意。 2. OpenPLC_Editor …

自动发卡平台源码优化版,支持个人免签支付

源码下载地址&#xff1a;自动发卡平台源码优化版.zip 环境要求&#xff1a; php 8.0 v1.2.6◂ 1.修复店铺共享连接时异常问题 2024-03-13 23:54:20 v1.2.5 1.[新增]用户界面硬币增款扣款操作 2.[新增]前台对接库存信息显示 3.[新增]文件缓存工具类[FileCache] 4.[新增]库存同…

基于单片机技术的门禁系统硬件设计研究

摘要:门禁系统在工业领域的应用十分广泛,如何利用单片机技术对门禁系统中的硬件进行管理与控制已经成为相关单位十分重要的研究课题之一。因此,文章设计了一套基于单片机技术的门禁系统硬件方案,旨在充分发挥单片机设备在自动化控制方面的优势,提高门禁系统的自动化水平。…

车载以太网AVB交换机 gptp透明时钟 5口 全千兆 SW1500

全千兆车载以太网交换机 一、产品简要分析 5端口千兆车载以太网交换机&#xff0c;包含4个通道的1000BASE-T1接口使用罗森博格H-MTD和泰科MATEnet双接口&#xff0c;1个通道1000BASE-T标准以太网(RJ45接口)&#xff0c;可以实现车载以太网多通道交换&#xff0c;千兆和百兆车载…

【数据结构】带头双向链表的实现

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《数据结构》 &#x1f389;道阻且长&#xff0c;行则将至 前言 带头双向链表是链表的一种&#xff0c;相较于单链表的实现&#xff0c;其更为简单 一.初识带头双向循环链表 带头…

【漏洞分析】浅析android手游lua脚本的加密与解密(二)

反编译本人用到的是luajit-decomp,这里需要注意,luajit-decomp默认的lua版本为5.1,luajit版本为2.0.2,我们需要下载对应lua和luajit的版本,编译后替换luajit-decomp下的lua51.dll、luajit.exe、jit文件夹。反编译时需要注意的文件和文件夹: 这里需要下载版本为2.1.0-bet…

用 AI 编程-释放ChatGPT的力量

最近读了本书&#xff0c;是 Sean A Williams 写的&#xff0c;感觉上还是相当不错的。一本薄薄的英文书&#xff0c;还真是写的相当好。如果你想看&#xff0c;还找不到&#xff0c;可以考虑私信我吧。 ChatGPT for Coders Unlock the Power of AI with ChatGPT: A Comprehens…

SAP-CO主数据之统计指标创建-<KK01>

公告&#xff1a;周一至周五每日一更&#xff0c;周六日存稿&#xff0c;请您点“关注”和“在看”&#xff0c;后续推送的时候不至于看不到每日更新内容&#xff0c;感谢。 目录 一、背景&#xff1a; 成本中心主数据创建&#xff1a;传送门 成本要素主数据创建&#xff1…

OpenHarmony实战开发-滑动容器组件Swiper的使用

介绍 本篇Codelab主要介绍了滑动容器组件Swiper的几种常见的应用场景&#xff0c;包括顶部导航、轮播图以及视频滑动播放。 相关概念 Swiper&#xff1a;滑动容器&#xff0c;提供子组件切换滑动的能力。Stack&#xff1a;堆叠容器&#xff0c;子组件按照顺序依次入栈&#x…

康耐视visionpro-CogFindLineTool工具详细说明

CogFindeLineTool功能说明: 检测图像的直线边缘,实现边缘的定位、测量。 CogFindeLineTool操作说明: ①.打开工具栏,双击或点击鼠标拖拽添加CogFindLineTool工具 ②.添加输入图像,点击鼠标右键“链接到”选择输入图像或以连线拖拽的方式选择相应输入图像 ③. 所选空间名…

振弦采集仪在预防地质灾害监测中的作用与应用前景

振弦采集仪在预防地质灾害监测中的作用与应用前景 振弦采集仪&#xff08;String Vibrating Sensor&#xff0c;简称SVM&#xff09;是一种用于地质灾害监测的重要仪器&#xff0c;它通过测量地面振动信号来预测和预警地质灾害的发生。SVM的作用在于提供实时、准确的地质灾害监…

威联通安装Kafka

最近在学习 Kafka 的知识&#xff0c;遇到一些问题网上搜到的信息不全。想要在本地安装一个 Kafka 进行验证&#xff0c;想到了之前买的 Nas 就开始折腾。 用 Docker 的方式安装 Kafka 现在的 Nas 很多都支持 Docker&#xff0c;我买的也支持。威联通的 Docker 叫 Container S…

AugmentedReality之路-通过蓝图启动AR相机(2)

本文实现打开AR相机和关闭AR相机功能&#xff0c;在主界面点击Start AR按钮后打开AR相机&#xff0c;在主界面点击Stop AR按钮后关闭AR相机 1、启动AR相关插件 通过Edit->Plugins启用AugmentedReality下面的所有插件 2、自定义Pawn 在Content->ARBase目录右键&…

如何降低 BlueNRG-LPS 的开机峰值电流

1. 前言 BlueNRG 系列存在开机瞬间会出现很大的峰值电流的现象&#xff0c;预计有 20ma 左右。针对此现象&#xff0c;经常有客户询问该峰值电流会不会导致设备工作异常&#xff1f;会不会导致电池使用寿命缩短&#xff08;考虑到一般纽扣电池能承受的峰值电流大概在 15ma 左右…

B64843-4M 1553B总线 控制时序、寄存器介绍。

B64843-4M系统架构 注: 1 、 CPU ADDRESS LATCH 信号由带地址 / 数据复用总线的处理器提供,对不带地址 / 数据复用总线的处理器,CPU ADDRESS LATCH 信号与 3.3V 信号连接。 2、如果 POLARITY_SEL="1" , RD/信号为高时读使能,为低时写使POLARITY_S…