Android 如何使用Python脚本通过ADB运行sqlite语句,以便从JSON文件填充表?
虽然标题可能不是很好,但我认为这种怀疑是正确的。我正在为Android开发,并在我的持久层上使用SQLite。为了进行测试(不是单元测试或仪器测试,只是开发测试,比如打开屏幕并检查一些数据以查看布局),我需要在数据库中填充数据——这是一件非常烦人的事情,因为我需要插入大量数据,我不想用它污染我的代码 我想用一种非常简单的方式来实现这一点,我可以将其重新用于我以后开发的任何应用程序、库或模块,因此我决定使用Android调试桥(ADB)来访问emulator shell,并从那里运行sql脚本来插入我想要的数据——从json文件读取。为此,我提出了以下脚本:Android 如何使用Python脚本通过ADB运行sqlite语句,以便从JSON文件填充表?,android,python,shell,sqlite,android-emulator,Android,Python,Shell,Sqlite,Android Emulator,虽然标题可能不是很好,但我认为这种怀疑是正确的。我正在为Android开发,并在我的持久层上使用SQLite。为了进行测试(不是单元测试或仪器测试,只是开发测试,比如打开屏幕并检查一些数据以查看布局),我需要在数据库中填充数据——这是一件非常烦人的事情,因为我需要插入大量数据,我不想用它污染我的代码 我想用一种非常简单的方式来实现这一点,我可以将其重新用于我以后开发的任何应用程序、库或模块,因此我决定使用Android调试桥(ADB)来访问emulator shell,并从那里运行sql脚本来插
import sys
import json
import subprocess
# ADDS ROOT DIR TO PATH
sys.path.insert(0, '..')
COMMANDS = "abd root ; adb remount ; adb shell; sqlite3 {} ; .headers on ; insert into {} ({}) values ({}); exit ;"
ERROR_INVALID_INPUT = "You must specify the TableName and database full path"
def get_columns_and_values(object):
columns = ""
values = ""
for key, value in object.items():
columns += str(key) + ","
values += str(value) + ","
return [columns, values]
def get_table_name():
return sys.argv[1]
def get_database_path():
return sys.argv[2]
def validate_input():
return len(sys.argv) == 3
def run_commands(columns, values):
formatted_commands = COMMANDS.format(
get_database_path(),
get_table_name(),
columns,
values
)
process = subprocess.Popen(formatted_commands.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
if validate_input():
with open(ARG_SAMPLE_JSON_FILE) as json_file:
data = json.load(json_file)
for object in data:
normalizedRow = get_columns_and_values(object)
run_commands(normalizedRow[0], normalizedRow[1])
else:
print ERROR_INVALID_INPUT
问题是:脚本从访问bash开始,然后进入emulator的shell,进入sqlite3命令行。当这种情况发生时,我不知道如何使用Python在那里运行命令——也许问题的标题是如何将Python中的命令运行到Android Emulator的shell中p
非常感谢您的帮助
p.S.:我知道有更优雅的方法来实现我想要的,比如切换Dagger2依赖项以提供模拟数据,但是这需要大量的配置和调试,有时,你只想快速开始在屏幕上看到东西。好的,我最终发现可以在一行中运行sqlite命令。下面的脚本正是我想要的:
import sys
import json
import subprocess
# ADDS ROOT DIR TO PATH
sys.path.insert(0, '..')
ARG_SAMPLE_JSON_FILE = "resources/WorkingDays.json"
CMD_SQL_INSERT = "adb shell sqlite3 {} \"INSERT INTO {} ({}) VALUES ({})\""
CMD_SQL_SELECT = "adb shell sqlite3 {} \"SELECT {} FROM {}\""
CMD_SQL_DELETE = "adb shell sqlite3 {} \"DELETE FROM {}\""
ACTION_INSERT = 'INSERT'
ACTION_DELETE = 'DELETE'
ACTION_SELECT = 'SELECT'
ERROR_INVALID_INPUT = "You must specify the table name, database full path and SQL action to be executed"
ERROR_INVALID_ACTION = "Unrecognized actions. Valid actions are: SELECT, DELETE and INSERT"
def get_columns_and_values(object):
columns = ""
values = ""
for key, value in object.items():
columns += str(key) + ","
if is_number(value):
values += str(value) + ","
else:
values += "'" + str(value) + "'" + ","
return [columns[:-1], values[:-1].replace("False", '0').replace("True", '1')]
def is_number(s):
try:
int(s)
return True
except ValueError:
return False
def get_json_file():
return sys.argv[1]
def get_table_name():
return sys.argv[2]
def get_database_path():
return sys.argv[3]
def get_action():
return sys.argv[4]
def validate_input():
return len(sys.argv) == 5
def run_commands(columns, values):
action = get_action()
if action == ACTION_SELECT:
formatted_command = CMD_SQL_SELECT.format(get_database_path(), columns, get_table_name())
elif action == ACTION_DELETE:
formatted_command = CMD_SQL_DELETE.format(get_database_path(), get_table_name())
elif action == ACTION_INSERT:
formatted_command = CMD_SQL_INSERT.format(get_database_path(), get_table_name(), columns, values)
else:
print ERROR_INVALID_ACTION
return
print "Executing command: {}".format(formatted_command)
process = subprocess.Popen(
formatted_command.split(),
stdout=subprocess.PIPE
)
output, error = process.communicate()
formatted_output = "OUTPUT: {}".format(output)
formatted_error = "ERROR: {}".format(error)
print formatted_output, formatted_error
if validate_input():
with open(get_json_file()) as json_file:
data = json.load(json_file)
for object in data:
normalizedRow = get_columns_and_values(object)
run_commands(normalizedRow[0], normalizedRow[1])
else:
print ERROR_INVALID_INPUT
好的,我最终发现您可以在一行中运行sqlite命令。下面的脚本正是我想要的:
import sys
import json
import subprocess
# ADDS ROOT DIR TO PATH
sys.path.insert(0, '..')
ARG_SAMPLE_JSON_FILE = "resources/WorkingDays.json"
CMD_SQL_INSERT = "adb shell sqlite3 {} \"INSERT INTO {} ({}) VALUES ({})\""
CMD_SQL_SELECT = "adb shell sqlite3 {} \"SELECT {} FROM {}\""
CMD_SQL_DELETE = "adb shell sqlite3 {} \"DELETE FROM {}\""
ACTION_INSERT = 'INSERT'
ACTION_DELETE = 'DELETE'
ACTION_SELECT = 'SELECT'
ERROR_INVALID_INPUT = "You must specify the table name, database full path and SQL action to be executed"
ERROR_INVALID_ACTION = "Unrecognized actions. Valid actions are: SELECT, DELETE and INSERT"
def get_columns_and_values(object):
columns = ""
values = ""
for key, value in object.items():
columns += str(key) + ","
if is_number(value):
values += str(value) + ","
else:
values += "'" + str(value) + "'" + ","
return [columns[:-1], values[:-1].replace("False", '0').replace("True", '1')]
def is_number(s):
try:
int(s)
return True
except ValueError:
return False
def get_json_file():
return sys.argv[1]
def get_table_name():
return sys.argv[2]
def get_database_path():
return sys.argv[3]
def get_action():
return sys.argv[4]
def validate_input():
return len(sys.argv) == 5
def run_commands(columns, values):
action = get_action()
if action == ACTION_SELECT:
formatted_command = CMD_SQL_SELECT.format(get_database_path(), columns, get_table_name())
elif action == ACTION_DELETE:
formatted_command = CMD_SQL_DELETE.format(get_database_path(), get_table_name())
elif action == ACTION_INSERT:
formatted_command = CMD_SQL_INSERT.format(get_database_path(), get_table_name(), columns, values)
else:
print ERROR_INVALID_ACTION
return
print "Executing command: {}".format(formatted_command)
process = subprocess.Popen(
formatted_command.split(),
stdout=subprocess.PIPE
)
output, error = process.communicate()
formatted_output = "OUTPUT: {}".format(output)
formatted_error = "ERROR: {}".format(error)
print formatted_output, formatted_error
if validate_input():
with open(get_json_file()) as json_file:
data = json.load(json_file)
for object in data:
normalizedRow = get_columns_and_values(object)
run_commands(normalizedRow[0], normalizedRow[1])
else:
print ERROR_INVALID_INPUT