我正在编写一个模块,以使用SQLAlchemy(SQLAlchemy == 1.3.5)和Python 3.6.8将东西记录到数据库中。
我尝试将日志添加到表中。
如果表不存在,我会收到“表不存在”错误,然后创建表(可以正常工作)。
问题在于,当我尝试将相同项目添加到会话中时,它将失败。似乎“提交”使它停在了轨道上。
我确实尝试使用了'exc.NoSuchTableError'异常,但这似乎并没有说明该表不存在。我还尝试了仅使用冲洗或仅使用提交的各种组合,但结果与输出中的结果相似。
我有一个单独的test.py文件,其中包含:
#!/usr/bin/env python
import ail
add_to_log = ail.add_to_log(
tool='ansible',
component='system management',
level=6,
description="This is a test message!",
)
ail.py模块:
#!/usr/bin/env python
import sqlalchemy as db
from sqlalchemy import exc
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy_filters import apply_filters
import pprint
import time
import re
def add_to_log(tool, component, description, level=6):
"""
Add an entry to the 'logs' table.
E.g: add_to_log = log.add_to_log(
tool='cims_import.py',
component='database',
level=6,
description="The CIMS import script was unable to access the CIMS database.",
)
:param tool: Tool the log item is for, e.g.: cims, spectrum, capm, nfa, etc.
:param component: The component the log relates to, e.g.: 'api', 'ssh' or 'backups'
:param level: 0=Emergency, 1=Alert, 2=Critical, 3=Error, 4=Warning, 5=Notice, 6=Informational, 7=Debug
:param description: Description of event added to the logs.
:return: dictionary containing results, e.g.: {'action': 'added'}
In the event of an error, a dict containing {'error': '<error_description>'} will be returned.
"""
try:
# Try to add log item to the 'logs' table:
logged_item = Log(
tool=tool,
component=component,
level=level,
description=description,
)
s2s.add(logged_item)
s2s.commit()
return {'action': 'added'}
except exc.SQLAlchemyError as e:
print("First attempt failed, creating database!")
# Unable to add the log item:
if re.search(r"Table '.*' doesn't exist", str(e)):
print("Table issue")
# The 'logs' table does not exist - try to create a new one:
try:
Base.metadata.tables["logs"].create(bind=s2)
except exc.SQLAlchemyError as e:
return {'error': e}
else:
print("Table success")
try:
print("Try add item again")
# Try to add the log item again:
logged_item = Log(
tool=tool,
component=component,
level=level,
description=description
)
print("going to add")
s2s.add(logged_item)
print("going to commit")
s2s.commit()
print("committed!")
return {'action': 'added'}
except exc.SQLAlchemyError as e:
return {'error': e}
else:
return {'error': e}
s2 = db.create_engine(
'mysql+mysqlconnector://user:password@server:port/s2db', pool_recycle=3600, echo=True)
session = sessionmaker()
session.configure(bind=s2)
s2s = session()
Base = declarative_base()
class Log(Base):
__tablename__ = 'logs'
id = db.Column(db.Integer(), primary_key=True, unique=True)
tool = db.Column(db.String(32), nullable=False)
component = db.Column(db.String(32), nullable=False)
level = db.Column(db.Integer(), default=0, nullable=False)
description = db.Column(db.String(256), nullable=False)
created = db.Column(db.DateTime(), server_default=db.func.now())
我确保数据库中不存在“日志”表并运行它:
首次运行时登录为:
(venv) [user@server venv]$ ./test.py
2019-07-11 23:40:32,608 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2019-07-11 23:40:32,608 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:40:32,611 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'lower_case_table_names'
2019-07-11 23:40:32,611 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:40:32,613 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2019-07-11 23:40:32,613 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:40:32,614 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
2019-07-11 23:40:32,614 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:40:32,615 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
2019-07-11 23:40:32,615 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:40:32,616 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-07-11 23:40:32,618 INFO sqlalchemy.engine.base.Engine INSERT INTO logs (tool, component, level, description) VALUES (%(tool)s, %(component)s, %(level)s, %(description)s)
2019-07-11 23:40:32,618 INFO sqlalchemy.engine.base.Engine {'tool': 'ansible', 'component': 'system management', 'level': 6, 'description': 'This is a test message!'}
2019-07-11 23:40:32,628 INFO sqlalchemy.engine.base.Engine ROLLBACK
First attempt failed, creating database!
Table issue
2019-07-11 23:40:32,688 INFO sqlalchemy.engine.base.Engine
CREATE TABLE logs (
id INTEGER NOT NULL AUTO_INCREMENT,
tool VARCHAR(32) NOT NULL,
component VARCHAR(32) NOT NULL,
level INTEGER NOT NULL,
description VARCHAR(256) NOT NULL,
created DATETIME DEFAULT now(),
PRIMARY KEY (id),
UNIQUE (id)
)
2019-07-11 23:40:32,688 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:40:33,034 INFO sqlalchemy.engine.base.Engine COMMIT
Table success
Try add item again
going to add
going to commit
(venv) [user@server venv]$
那么为什么它不提交,甚至在“准备提交”之后不显示其他错误消息?
因此,在此阶段,表本身已经创建,但是没有日志条目。
如果我再次运行它(现在已经创建了表),则可以多次运行:
(venv) [user@server venv]$ test.py
2019-07-11 23:42:45,144 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2019-07-11 23:42:45,144 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:42:45,149 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'lower_case_table_names'
2019-07-11 23:42:45,149 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:42:45,153 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2019-07-11 23:42:45,153 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:42:45,155 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
2019-07-11 23:42:45,155 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:42:45,156 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
2019-07-11 23:42:45,157 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:42:45,158 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-07-11 23:42:45,161 INFO sqlalchemy.engine.base.Engine INSERT INTO logs (tool, component, level, description) VALUES (%(tool)s, %(component)s, %(level)s, %(description)s)
2019-07-11 23:42:45,161 INFO sqlalchemy.engine.base.Engine {'tool': 'ansible', 'component': 'system management', 'level': 6, 'description': 'This is a test message!'}
2019-07-11 23:42:45,164 INFO sqlalchemy.engine.base.Engine COMMIT
(venv) [user@server venv]$
表的创建几乎干扰了会话(s2s)。
有人可以提供任何建议/帮助来说明为什么发生这种情况吗?
答案 0 :(得分:0)
好吧,所以我在youtube上观看了一个视频,当他们提到回滚时,我以为我必须回滚,但似乎本次会议并不是要一次规整所有会议的会议(至少看起来像这样)据我所知,它仅是本周从SQLAlchemy开始!)。
创建和关闭会话似乎更好。这似乎对我有用:
我删除了全局作用域下的会话设置,只是将2个“向db添加日志项”块替换为:
# NOTE: setup new session:
s2s = session()
logged_item = Log(
tool=tool,
component=component,
level=level,
description=description
)
print("going to add")
s2s.add(logged_item)
print("going to commit")
s2s.commit()
print("committed!")
# NOTE: close session:
s2s.close()
return {'action': 'added'}
结果:
(venv) [user@server venv]$ ./test.py
2019-07-11 23:58:44,259 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2019-07-11 23:58:44,259 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:58:44,264 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'lower_case_table_names'
2019-07-11 23:58:44,264 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:58:44,268 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2019-07-11 23:58:44,268 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:58:44,270 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
2019-07-11 23:58:44,270 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:58:44,272 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
2019-07-11 23:58:44,272 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:58:44,274 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-07-11 23:58:44,276 INFO sqlalchemy.engine.base.Engine INSERT INTO logs (tool, component, level, description) VALUES (%(tool)s, %(component)s, %(level)s, %(description)s)
2019-07-11 23:58:44,277 INFO sqlalchemy.engine.base.Engine {'tool': 'ansible', 'component': 'system management', 'level': 6, 'description': 'This is a test message!'}
2019-07-11 23:58:44,278 INFO sqlalchemy.engine.base.Engine ROLLBACK
First attempt failed, creating database!
Table issue
2019-07-11 23:58:44,334 INFO sqlalchemy.engine.base.Engine
CREATE TABLE logs (
id INTEGER NOT NULL AUTO_INCREMENT,
tool VARCHAR(32) NOT NULL,
component VARCHAR(32) NOT NULL,
level INTEGER NOT NULL,
description VARCHAR(256) NOT NULL,
created DATETIME DEFAULT now(),
PRIMARY KEY (id),
UNIQUE (id)
)
2019-07-11 23:58:44,334 INFO sqlalchemy.engine.base.Engine {}
2019-07-11 23:58:44,368 INFO sqlalchemy.engine.base.Engine COMMIT
Table success
Try add item again
going to add
going to commit
2019-07-11 23:58:44,370 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2019-07-11 23:58:44,370 INFO sqlalchemy.engine.base.Engine INSERT INTO logs (tool, component, level, description) VALUES (%(tool)s, %(component)s, %(level)s, %(description)s)
2019-07-11 23:58:44,371 INFO sqlalchemy.engine.base.Engine {'tool': 'ansible', 'component': 'system management', 'level': 6, 'description': 'This is a test message!'}
2019-07-11 23:58:44,374 INFO sqlalchemy.engine.base.Engine COMMIT
committed!
(venv) [user@server venv]$