我需要对SQLite数据库执行UPSERT/INSERT或UPDATE.
在许多情况下,命令INSERT OR REPLACE可能很有用.但是如果你想因为外键而使你的id保持自动增量,那么它不起作用,因为它删除了行,创建了一个新行,因此这个新行有一个新的ID.
这将是表格:
播放器 - (id上的主键,user_name唯一)
| id | user_name | age |
------------------------------
| 1982 | johnny | 23 |
| 1983 | steven | 29 |
| 1984 | pepee | 40 |
Run Code Online (Sandbox Code Playgroud) 如何构造将参数直接传递给自己的类的对象?
像这样的东西:
Dim this_employee as Employee
Set this_employee = new Employee(name:="Johnny", age:=69)
Run Code Online (Sandbox Code Playgroud)
无法做到这一点非常烦人,你最终会得到一些肮脏的解决方案来解决这个问题.
我非常喜欢遵循PEP 8中指定的样式标准.我有一个自动检查它的linter,因此我的代码肯定更好.
在PEP 8中只有一点,E251和E221感觉不太好.来自JavaScript背景,我曾经将变量赋值对齐如下:
var var1 = 1234;
var2 = 54;
longer_name = 'hi';
var lol = {
'that' : 65,
'those' : 87,
'other_thing' : true
};
Run Code Online (Sandbox Code Playgroud)
在我看来,这大大提高了可读性.问题是,PEP 8不推荐这样做.对于词典,并不是那么糟糕,因为在冒号后允许空格:
dictionary = {
'something': 98,
'some_other_thing': False
}
Run Code Online (Sandbox Code Playgroud)
我可以在没有对齐的情况下"生活"变量赋值,但我完全不喜欢的是不能在函数调用中传递命名参数,如下所示:
some_func(length= 40,
weight= 900,
lol= 'troll',
useless_var= True,
intelligence=None)
Run Code Online (Sandbox Code Playgroud)
所以,我最终做的是使用字典,如下所示:
specs = {
'length': 40,
'weight': 900,
'lol': 'troll',
'useless_var': True,
'intelligence': None
}
some_func(**specs)
Run Code Online (Sandbox Code Playgroud)
或者只是简单地
some_func(**{'length': 40,
'weight': 900,
'lol': 'troll',
'useless_var': True,
'intelligence': None})
Run Code Online (Sandbox Code Playgroud)
但我觉得这个工作比忽略PEP 8 E251/E221更糟糕.
什么是最佳做法?
多年后编辑 …
我找不到任何PEP参考这个细节.函数定义后必须有一个空行?
我应该这样做:
def hello_function():
return 'hello'
Run Code Online (Sandbox Code Playgroud)
或者我是这样做的:
def hello_function():
return 'hello'
Run Code Online (Sandbox Code Playgroud)
使用docstrings时,同样的问题适用:
这个:
def hello_function():
"""
Important function
"""
return 'hello'
Run Code Online (Sandbox Code Playgroud)
或这个
def hello_function():
"""
Important function
"""
return 'hello'
Run Code Online (Sandbox Code Playgroud)
编辑
这就是PEP在空白行中所说的内容,正如FoxMaSk所评论的那样,但它没有在这个细节上说什么.
空白行
使用两个空行分隔顶级函数和类定义.
类中的方法定义由单个空行分隔.
可以使用额外的空白行(谨慎地)来分离相关功能组.在一堆相关的单行(例如,一组虚拟实现)之间可以省略空行.
在函数中使用空行,谨慎地指示逻辑部分.
Python接受control-L(即^ L)换页符作为空格; 许多工具将这些字符视为页面分隔符,因此您可以使用它们来分隔文件相关部分的页面.请注意,某些编辑器和基于Web的代码查看器可能无法将control-L识别为换页符,并且会在其位置显示另一个字形.
我在SQLAlchemy中遇到了一个问题,并在编写时找到了解决方案.无论如何,我发布它,以防它有助于某人:)
假设我有很多关系似乎有效(至少我可以取儿)三个表:帖子,标签和post_tags.
import sqlalchemy as alc
class Tag(Base):
__tablename__ = 'tags'
id = alc.Column(alc.Integer, primary_key=True)
name = alc.Column(alc.String)
accepted = alc.Column(alc.Integer)
posts = relationship('Post', secondary=post_tags)
class Post(Base):
__tablename__ = 'posts'
id = alc.Column(alc.Integer, primary_key=True)
text = alc.Column(alc.String)
date_out = alc.Column(alc.Date)
tags = relationship('Mistake_Code', secondary=post_tags)
# relational table
post_tags = alc.Table('check_point_mistakes',
Base.metadata,
alc.Column('post_id', alc.Integer,ForeignKey('posts.id')),
alc.Column('tag_id', alc.Integer, alc.ForeignKey('tags.id')))
Run Code Online (Sandbox Code Playgroud)
现在我的问题是我想先在Post中使用date_out进行过滤.我可以这样得到它:
# assume start_date and end_date
query = (
session.query(Post)
.filter(Post.date_out.between(start_date, end_date))
)
Run Code Online (Sandbox Code Playgroud)
但是如何同时按标签过滤?
假设我们有一个SQL语句,只需要在对DB执行之前用参数完成.例如:
sql = '''
SELECT id, price, date_out
FROM sold_items
WHERE date_out BETWEEN ? AND ?
'''
database_cursor.execute(sql, (start_date, end_date))
Run Code Online (Sandbox Code Playgroud)
如何获取解析和执行的字符串?,如下所示:
SELECT id, price, date_out
FROM sold_items
WHERE date_out BETWEEN 2010-12-05 AND 2011-12-01
Run Code Online (Sandbox Code Playgroud)
在这个简单的情况下,它不是很重要,但我有其他更复杂的SQL语句,为了调试目的,我想在我的sqlite管理器中自己执行它们并检查结果.
提前致谢
我想将我的应用程序的文件放在文件夹/ Files下,而/ UnitTests中的测试单元,这样我就可以清楚地分开app和test了.
为了能够使用与mainApp.py相同的模块路由,我在根文件夹中创建了一个testController.py.
mainApp.py
testController.py
Files
|__init__.py
|Controllers
| blabla.py
| ...
UnitTests
|__init__.py
|test_something.py
Run Code Online (Sandbox Code Playgroud)
因此,如果在test_something.py中我想测试/Files/Controllers/blabla.py中的一个函数,我尝试以下方法:
import unittest
import Files.Controllers.blabla as blabla
class TestMyUnit(unittest.TestCase):
def test_stupid(self):
self.assertTrue(blabla.some_function())
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
然后从文件testController.py中,我执行以下代码:
import TestUnits.test_something as my_test
my_test.unittest.main()
Run Code Online (Sandbox Code Playgroud)
哪个输出没有失败,但没有执行测试
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
[Finished in 0.3s]
Run Code Online (Sandbox Code Playgroud)
我尝试过一个没有依赖关系的测试,如果执行" main "工作,但是当从外部调用时,输出相同的:
import unittest
def tested_unit():
return True
class TestMyUnit(unittest.TestCase):
def test_stupid(self):
self.assertTrue(tested_unit())
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
问题:我如何让这个工作?
我正在重新组织我的代码,从而创建新的命名空间.我正在为模块更改"静态"类(每种方法中带有@staticmethod的类).这是要走的路,对吧?
问题是我对如何在这些模块之间共享资源有疑问.
假设我有一个模块,我从中与数据库建立了所有连接,当然所有类/方法都共享存储数据库游标的变量(我使用的是SQLite).现在,在不同的模块中,他们还必须共享光标.

所以,我的想法:
在每个模块中声明全局变量.但全球化是邪恶的,吃孩子并偷走我们的工作.所以我不知道这是不是要走的路.
'''Sub Module 1'''
global database_cursor
Run Code Online (Sandbox Code Playgroud)使用原始database_cursor导入"father"database_module并使用如下内容:
'''Sub Module 1'''
db_cursor = database_module.database_cursor
Run Code Online (Sandbox Code Playgroud)在这种情况下,第二个看起来很好,但我认为在许多情况下会导致递归导入,我想这是要避免的.
我正在测试一个继承自另一个非常复杂的类,使用DB连接方法和一堆依赖.我想模拟它的基类,以便我可以很好地使用子类中定义的方法,但是在我从一个模拟类继承的那一刻,对象本身变成了一个模拟并丢失了它的所有方法.
我怎么能模拟一个超类呢?
或多或少的情况可归纳为:
import mock
ClassMock = mock.MagicMock()
class RealClass(ClassMock):
def lol(self):
print 'lol'
real = RealClass()
real.lol() # Does not print lol, but returns another mock
print real # prints <MagicMock id='...'>
Run Code Online (Sandbox Code Playgroud)
这是一个简化的案例.实际发生的是RealClass扩展AnotherClass,但我设法拦截AnotherClass并用模拟替换它.
我有一个对象列表,我想以一种方式过滤列表,因此每个属性值只有一个出现.
例如,假设我有三个对象
obj1.my_attr = 'a'
obj2.my_attr = 'b'
obj3.my_attr = 'b'
obj_list = [obj1, obj2, obj3]
Run Code Online (Sandbox Code Playgroud)
最后,我想得到[obj1, obj2].实际上顺序并不重要,所以[obj1, obj3]完全一样好.
首先,我想到了典型的命令式笨重方式,如下所示:
record = set()
result = []
for obj in obj_list:
if obj.my_attr not in record:
record.add(obj.my_attr)
result.append(obj)
Run Code Online (Sandbox Code Playgroud)
然后,我将其与字典匹配,使用键覆盖任何先前的条目,最后提取值:
result = {obj.my_attr: obj for obj in obj_list}.values()
Run Code Online (Sandbox Code Playgroud)
这个看起来不错,但我想知道是否有更优雅,高效或功能性的方法来实现这一目标.也许隐藏在标准库中的一些甜蜜的东西...在此先感谢.
python ×8
coding-style ×2
module ×2
sqlite ×2
unit-testing ×2
class ×1
constructor ×1
database ×1
factory ×1
filtering ×1
globals ×1
inheritance ×1
many-to-many ×1
mocking ×1
namespaces ×1
oop ×1
orm ×1
pep ×1
pep8 ×1
sql ×1
sqlalchemy ×1
styles ×1
tdd ×1
upsert ×1
vba ×1