4 import sqlalchemy
.types
6 from .db
import connect
, metadata
, tables
as tables_module
15 # Find the command as a function in this file
16 func
= globals().get(command
, None)
17 if func
and callable(func
) and command
!= 'main':
23 def csvimport(engine_uri
, directory
='.'):
26 from sqlalchemy
.orm
.attributes
import instrumentation_registry
28 session
= connect(engine_uri
)
32 # SQLAlchemy is retarded and there is no way for me to get a list of ORM
33 # classes besides to inspect the module they all happen to live in for
34 # things that look right.
35 table_base
= tables_module
.TableBase
36 orm_classes
= {} # table object => table class
38 for name
in dir(tables_module
):
39 # dir() returns strings! How /convenient/.
40 thingy
= getattr(tables_module
, name
)
42 if not isinstance(thingy
, type):
45 elif not issubclass(thingy
, table_base
):
46 # Not a declarative table; bail
48 elif thingy
== table_base
:
49 # Declarative table base, so not a real table; bail
52 # thingy is definitely a table class! Hallelujah.
53 orm_classes
[thingy
.__table__
] = thingy
55 # Okay, run through the tables and actually load the data now
56 for table_obj
in metadata
.sorted_tables
:
57 table_class
= orm_classes
[table_obj
]
58 table_name
= table_obj
.name
60 # Print the table name but leave the cursor in a fixed column
61 print table_name
+ '...', ' ' * (40 - len(table_name
)),
64 csvfile
= open("%s/%s.csv" %
(directory
, table_name
), 'rb')
66 # File doesn't exist; don't load anything!
70 reader
= csv
.reader(csvfile
, lineterminator
='\n')
71 column_names
= [unicode(column
) for column
in reader
.next()]
76 for column_name
, value
in zip(column_names
, csvs
):
77 column
= table_obj
.c
[column_name
]
78 if column
.nullable
and value
== '':
79 # Empty string in a nullable column really means NULL
81 elif isinstance(column
.type, sqlalchemy
.types
.Boolean
):
82 # Boolean values are stored as string values 0/1, but both
83 # of those evaluate as true; SQLA wants True/False
89 # Otherwise, unflatten from bytes
90 value
= value
.decode('utf-8')
92 setattr(row
, column_name
, value
)
100 def csvexport(engine_uri
, directory
='.'):
102 session
= connect(engine_uri
)
104 for table_name
in sorted(metadata
.tables
.keys()):
106 table
= metadata
.tables
[table_name
]
108 writer
= csv
.writer(open("%s/%s.csv" %
(directory
, table_name
), 'wb'),
110 columns
= [col
.name
for col
in table
.columns
]
111 writer
.writerow(columns
)
113 for row
in session
.query(table
).all():
116 # Convert Pythony values to something more universal
117 val
= getattr(row
, col
)
125 val
= unicode(val
).encode('utf-8')
129 writer
.writerow(csvs
)
133 print u
"""pokedex -- a command-line Pokédex interface
135 help Displays this message.
137 These commands are only useful for developers:
138 csvimport {uri} [dir] Import data from a set of CSVs to the database
140 csvexport {uri} [dir] Export data from the database given by the URI
142 Directory defaults to cwd.